From 84afc50cd30f2f84043959067d21816f991baf7d Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 2 Mar 2022 11:38:22 +0800 Subject: [PATCH 001/179] 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 002/179] 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 003/179] 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 004/179] 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 005/179] 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 006/179] 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 007/179] 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 008/179] 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 009/179] 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 010/179] 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 011/179] 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 012/179] 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 013/179] 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 014/179] 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 015/179] 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 016/179] 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 017/179] 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(), From 733b6f71768f65a10e05c6c13d21680be96a3dc3 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 6 Mar 2022 22:02:09 +0800 Subject: [PATCH 018/179] feat: disable grid --- .../app_flowy/lib/workspace/presentation/plugins/grid/grid.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart index b73970508c..cf6b4c9032 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => true; + bool get creatable => false; } class GridPlugin extends Plugin { From 1c1e9551513c14b2924c1c31c1d5668ffb350fd6 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 7 Mar 2022 08:30:59 +0800 Subject: [PATCH 019/179] chore: set error_task script --- frontend/Makefile.toml | 6 ++++++ frontend/rust-lib/dart-ffi/Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index e661a425b6..4a492f4671 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -9,6 +9,12 @@ extend = [ { path = "scripts/makefile/flutter.toml" }, ] +[config] +on_error_task = "catch" + +[tasks.catch] +run_task = {name = ["restore-crate-type"]} + [env] RUST_LOG = "info" CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..df26694331 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 static lib +crate-type = ["staticlib"] [dependencies] From 0502eec71785d732b0ec101eac88581c4d970d7e Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 7 Mar 2022 20:51:13 +0800 Subject: [PATCH 020/179] chore: config plugin display --- .../app_flowy/lib/workspace/presentation/home/home_stack.dart | 2 +- .../workspace/presentation/plugins/doc/src/document_page.dart | 3 +-- .../lib/workspace/presentation/plugins/grid/grid.dart | 2 +- .../workspace/presentation/plugins/grid/src/layout/sizes.dart | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart b/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart index 8e249ab9c5..65e315f56d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart @@ -168,7 +168,7 @@ class HomeStackManager { index: getIt().indexOf(notifier.plugin.ty), children: getIt().supportPluginTypes.map((pluginType) { if (pluginType == notifier.plugin.ty) { - return notifier.plugin.display.buildWidget(); + return notifier.plugin.display.buildWidget().padding(horizontal: 40, vertical: 28); } else { return const BlankPage(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart index 30b88e652f..031edb93fd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart @@ -10,7 +10,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; -import 'package:styled_widget/styled_widget.dart'; import 'styles.dart'; import 'widget/banner.dart'; @@ -82,7 +81,7 @@ class _DocumentPageState extends State { _renderToolbar(controller), const VSpace(10), ], - ).padding(horizontal: 40, top: 28), + ), ), ], ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart index cf6b4c9032..b73970508c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => false; + bool get creatable => true; } class GridPlugin extends Plugin { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index e833df5cc4..13f7200ceb 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -10,7 +10,7 @@ class GridSize { static double get scrollBarSize => 12 * scale; static double get headerHeight => 50 * scale; - static double get rowHeight => 50 * scale; + static double get rowHeight => 36 * scale; static double get footerHeight => 40 * scale; static double get firstHeaderPadding => 20 * scale; } From 54cf4518266116bdf05af457ff2b2d28853a4d30 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 8 Mar 2022 15:25:56 +0800 Subject: [PATCH 021/179] feat: config textfield cell --- .../lib/startup/home_deps_resolver.dart | 37 ++-- .../workspace/application/app/prelude.dart | 3 + .../workspace/application/doc/prelude.dart | 4 + .../lib/workspace/application/grid/data.dart | 35 ++++ .../workspace/application/grid/grid_bloc.dart | 36 +--- .../workspace/application/grid/prelude.dart | 5 + .../workspace/application/grid/row_bloc.dart | 50 ++++++ .../application/grid/row_service.dart | 10 ++ .../workspace/application/home/prelude.dart | 1 + .../workspace/application/menu/prelude.dart | 2 + .../workspace/application/trash/prelude.dart | 3 + .../workspace/application/view/prelude.dart | 3 + .../application/workspace/prelude.dart | 3 + .../home/menu/app/header/header.dart | 4 +- .../plugins/grid/src/grid_page.dart | 12 +- .../plugins/grid/src/layout/layout.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 7 +- .../src/widgets/content/cell_builder.dart | 2 +- .../src/widgets/content/cell_container.dart | 30 ++-- .../grid/src/widgets/content/grid_cell.dart | 92 +++++++--- .../grid/src/widgets/content/grid_row.dart | 86 +++++----- .../grid/src/widgets/footer/grid_footer.dart | 2 +- .../grid/src/widgets/header/header_cell.dart | 2 +- .../flowy-grid-data-model/grid.pb.dart | 42 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 9 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../flowy-grid/src/services/grid_builder.rs | 28 +-- .../flowy-grid/src/services/grid_editor.rs | 12 +- .../src/entities/grid.rs | 49 +++++- .../src/protobuf/model/grid.rs | 161 +++++++++++++++--- .../src/protobuf/proto/grid.proto | 3 + 31 files changed, 517 insertions(+), 222 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/app/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/doc/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/data.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/home/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/menu/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/trash/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/view/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/workspace/prelude.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index f8c8d60e8f..9a2a47301e 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -1,26 +1,14 @@ import 'package:app_flowy/user/application/user_listener.dart'; import 'package:app_flowy/user/application/user_service.dart'; -import 'package:app_flowy/workspace/application/app/app_bloc.dart'; -import 'package:app_flowy/workspace/application/app/app_listener.dart'; -import 'package:app_flowy/workspace/application/app/app_service.dart'; -import 'package:app_flowy/workspace/application/doc/doc_bloc.dart'; -import 'package:app_flowy/workspace/application/doc/doc_service.dart'; -import 'package:app_flowy/workspace/application/doc/share_bloc.dart'; -import 'package:app_flowy/workspace/application/doc/share_service.dart'; -import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/grid_service.dart'; -import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart'; -import 'package:app_flowy/workspace/application/menu/menu_bloc.dart'; -import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart'; -import 'package:app_flowy/workspace/application/trash/trash_bloc.dart'; -import 'package:app_flowy/workspace/application/trash/trash_listener.dart'; -import 'package:app_flowy/workspace/application/trash/trash_service.dart'; -import 'package:app_flowy/workspace/application/view/view_bloc.dart'; -import 'package:app_flowy/workspace/application/view/view_listener.dart'; -import 'package:app_flowy/workspace/application/view/view_service.dart'; -import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart'; -import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart'; -import 'package:app_flowy/workspace/application/workspace/workspace_service.dart'; +import 'package:app_flowy/workspace/application/app/prelude.dart'; +import 'package:app_flowy/workspace/application/doc/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/application/trash/prelude.dart'; +import 'package:app_flowy/workspace/application/workspace/prelude.dart'; +import 'package:app_flowy/workspace/application/view/prelude.dart'; +import 'package:app_flowy/workspace/application/home/prelude.dart'; +import 'package:app_flowy/workspace/application/menu/prelude.dart'; + import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; @@ -107,6 +95,13 @@ class HomeDepsResolver { ), ); + getIt.registerFactoryParam( + (data, _) => RowBloc( + data: data, + service: RowService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); diff --git a/frontend/app_flowy/lib/workspace/application/app/prelude.dart b/frontend/app_flowy/lib/workspace/application/app/prelude.dart new file mode 100644 index 0000000000..f8477049d3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/app/prelude.dart @@ -0,0 +1,3 @@ +export 'app_bloc.dart'; +export 'app_listener.dart'; +export 'app_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/doc/prelude.dart b/frontend/app_flowy/lib/workspace/application/doc/prelude.dart new file mode 100644 index 0000000000..f2befe4cf0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/doc/prelude.dart @@ -0,0 +1,4 @@ +export 'doc_bloc.dart'; +export 'doc_service.dart'; +export 'share_bloc.dart'; +export 'share_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart new file mode 100644 index 0000000000..6c815b7f35 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -0,0 +1,35 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; + +class GridInfo { + List rows; + List fields; + + GridInfo({ + required this.rows, + required this.fields, + }); + + GridRowData rowAtIndex(int index) { + final row = rows[index]; + return GridRowData( + row: row, + fields: fields, + cellMap: row.cellByFieldId, + ); + } + + int numberOfRows() { + return rows.length; + } +} + +class GridRowData { + Row row; + List fields; + Map cellMap; + GridRowData({ + required this.row, + required this.fields, + required this.cellMap, + }); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index b915435343..500db75bf3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -7,6 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'data.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -21,7 +22,7 @@ class GridBloc extends Bloc { on( (event, emit) async { await event.map( - initial: (Initial value) async { + initial: (InitialGrid value) async { await _loadGrid(emit); await _loadFields(emit); await _loadGridInfo(emit); @@ -88,7 +89,7 @@ class GridBloc extends Bloc { @freezed abstract class GridEvent with _$GridEvent { - const factory GridEvent.initial() = Initial; + const factory GridEvent.initial() = InitialGrid; const factory GridEvent.rename(String gridId, String name) = _Rename; const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; @@ -113,34 +114,3 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.loading() = _Loading; const factory GridLoadingState.finish(Either successOrFail) = _Finish; } - -class GridInfo { - List rows; - List fields; - - GridInfo({ - required this.rows, - required this.fields, - }); - - RowInfo rowInfoAtIndex(int index) { - final row = rows[index]; - return RowInfo( - fields: fields, - cellMap: row.cellByFieldId, - ); - } - - int numberOfRows() { - return rows.length; - } -} - -class RowInfo { - List fields; - Map cellMap; - RowInfo({ - required this.fields, - required this.cellMap, - }); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart new file mode 100644 index 0000000000..bf48b7cc8b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -0,0 +1,5 @@ +export 'grid_bloc.dart'; +export 'row_bloc.dart'; +export 'row_service.dart'; +export 'grid_service.dart'; +export 'data.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart new file mode 100644 index 0000000000..8feb26e4c7 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -0,0 +1,50 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:dartz/dartz.dart'; +import 'dart:async'; +import 'data.dart'; +import 'row_service.dart'; + +part 'row_bloc.freezed.dart'; + +class RowBloc extends Bloc { + final RowService service; + final GridRowData data; + + RowBloc({required this.data, required this.service}) : super(RowState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_InitialRow value) async {}, + createRow: (_CreateRow value) {}, + highlightRow: (_HighlightRow value) { + emit(state.copyWith( + isHighlight: value.rowId.fold(() => false, (rowId) => rowId == data.row.id), + )); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class RowEvent with _$RowEvent { + const factory RowEvent.initial() = _InitialRow; + const factory RowEvent.createRow() = _CreateRow; + const factory RowEvent.highlightRow(Option rowId) = _HighlightRow; +} + +@freezed +abstract class RowState with _$RowState { + const factory RowState({ + required bool isHighlight, + }) = _RowState; + + factory RowState.initial() => const RowState(isHighlight: false); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart new file mode 100644 index 0000000000..ad04b0add2 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -0,0 +1,10 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; + +class RowService { + Future> createRow({required String gridId}) { + return GridEventCreateRow(GridId(value: gridId)).send(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/home/prelude.dart b/frontend/app_flowy/lib/workspace/application/home/prelude.dart new file mode 100644 index 0000000000..8d1173c2d6 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/home/prelude.dart @@ -0,0 +1 @@ +export 'home_listen_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/menu/prelude.dart b/frontend/app_flowy/lib/workspace/application/menu/prelude.dart new file mode 100644 index 0000000000..0bf94ea60b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/menu/prelude.dart @@ -0,0 +1,2 @@ +export 'menu_bloc.dart'; +export 'menu_user_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/trash/prelude.dart b/frontend/app_flowy/lib/workspace/application/trash/prelude.dart new file mode 100644 index 0000000000..5a638a58d1 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/trash/prelude.dart @@ -0,0 +1,3 @@ +export 'trash_bloc.dart'; +export 'trash_listener.dart'; +export 'trash_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/view/prelude.dart b/frontend/app_flowy/lib/workspace/application/view/prelude.dart new file mode 100644 index 0000000000..f789b90fcd --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/view/prelude.dart @@ -0,0 +1,3 @@ +export 'view_bloc.dart'; +export 'view_listener.dart'; +export 'view_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/workspace/prelude.dart b/frontend/app_flowy/lib/workspace/application/workspace/prelude.dart new file mode 100644 index 0000000000..129462beb0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/workspace/prelude.dart @@ -0,0 +1,3 @@ +export 'welcome_bloc.dart'; +export 'workspace_listener.dart'; +export 'workspace_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart index 58ebabc0c2..da20eafc7b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart @@ -37,7 +37,7 @@ class MenuAppHeader extends StatelessWidget { _renderExpandedIcon(context, theme), // HSpace(MenuAppSizes.iconPadding), _renderTitle(context, theme), - _renderAddButton(context), + _renderCreateViewButton(context), ], ), ); @@ -99,7 +99,7 @@ class MenuAppHeader extends StatelessWidget { ); } - Widget _renderAddButton(BuildContext context) { + Widget _renderCreateViewButton(BuildContext context) { return Tooltip( message: LocaleKeys.menuAppHeader_addPageTooltip.tr(), child: AddButton( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index e53a2f01e2..ae3934b7cb 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; @@ -135,10 +136,13 @@ class _GridBodyState extends State { Widget _buildRows(GridInfo gridInfo) { return SliverList( - delegate: SliverChildBuilderDelegate((context, index) { - final rowInfo = gridInfo.rowInfoAtIndex(index); - return RepaintBoundary(child: GridRowWidget(rowInfo)); - }, childCount: gridInfo.numberOfRows()), + delegate: SliverChildBuilderDelegate( + (context, index) { + final data = gridInfo.rowAtIndex(index); + return RepaintBoundary(child: GridRowWidget(data)); + }, + childCount: gridInfo.numberOfRows(), + ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index a44ad20d39..5b58d3c1c5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -8,6 +8,6 @@ class GridLayout { final fieldsWidth = fields.map((field) => field.width.toDouble()).reduce((value, element) => value + element); - return fieldsWidth + GridSize.firstHeaderPadding; + return fieldsWidth + GridSize.startHeaderPadding; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 13f7200ceb..e577311200 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -1,8 +1,8 @@ class GridInsets { static double scale = 1; - static double get horizontal => 6 * scale; - static double get vertical => 6 * scale; + static double get horizontal => 8 * scale; + static double get vertical => 8 * scale; } class GridSize { @@ -10,7 +10,6 @@ class GridSize { static double get scrollBarSize => 12 * scale; static double get headerHeight => 50 * scale; - static double get rowHeight => 36 * scale; static double get footerHeight => 40 * scale; - static double get firstHeaderPadding => 20 * scale; + static double get startHeaderPadding => 30 * scale; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 1c02664c86..efe5a0bd3e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -4,7 +4,7 @@ import 'grid_cell.dart'; class GridCellBuilder { static GridCellWidget buildCell(Field? field, Cell? cell) { if (field == null || cell == null) { - return const BlankCell(); + return GridTextCell("123123123"); } switch (field.fieldType) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index edd0de5076..03f0e82115 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,32 +1,26 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; -import 'cell_decoration.dart'; -import 'grid_cell.dart'; class CellContainer extends StatelessWidget { - final GridCellWidget child; + final Widget child; final double width; - const CellContainer({Key? key, required this.child, required this.width}) : super(key: key); + const CellContainer({ + Key? key, + required this.child, + required this.width, + }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, - onTap: () { - // context - // .read() - // .add(HomeEvent.setEditPannel(CellEditPannelContext())); - }, - child: MouseHoverBuilder( - builder: (_, isHovered) => Container( - width: width, - decoration: CellDecoration.box( - color: isHovered ? Colors.red.withOpacity(.1) : Colors.transparent, - ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - child: child, + onTap: () {}, + child: Container( + constraints: BoxConstraints( + maxWidth: width, ), + padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + child: Center(child: IntrinsicHeight(child: child)), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 00e6fad6af..5c0dbabfea 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -1,6 +1,12 @@ +import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; +import 'package:app_flowy/workspace/presentation/home/menu/app/header/add_button.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_decoration.dart'; // ignore: import_of_legacy_library_into_null_safe @@ -13,12 +19,25 @@ abstract class GridCellWidget extends StatelessWidget { } class GridTextCell extends GridCellWidget { - final String content; - const GridTextCell(this.content, {Key? key}) : super(key: key); + late final TextEditingController _controller; + + GridTextCell(String content, {Key? key}) : super(key: key) { + _controller = TextEditingController(text: content); + } @override Widget build(BuildContext context) { - return Text(content); + return TextField( + controller: _controller, + onChanged: (value) {}, + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + ); } } @@ -72,29 +91,64 @@ class BlankCell extends GridCellWidget { } class RowLeading extends StatelessWidget { - const RowLeading({Key? key}) : super(key: key); + final String rowId; + const RowLeading({required this.rowId, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - // return Expanded( - // child: Container( - // color: Colors.white10, - // width: GridSize.firstHeaderPadding, + return BlocBuilder( + builder: (context, state) { + if (state.isHighlight) { + return Row( + children: const [ + CreateRowButton(), + ], + ); + } + + return const Spacer(); + }, + ); + + // return GestureDetector( + // behavior: HitTestBehavior.translucent, + // onTap: () {}, + // child: MouseHoverBuilder( + // builder: (_, isHovered) => Container( + // width: GridSize.startHeaderPadding, + // decoration: CellDecoration.box( + // color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, + // ), + // padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + // ), // ), // ); + } +} - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () {}, - child: MouseHoverBuilder( - builder: (_, isHovered) => Container( - width: GridSize.firstHeaderPadding, - decoration: CellDecoration.box( - color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, - ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - ), +class CreateRowButton extends StatelessWidget { + const CreateRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Tooltip( + message: '', + child: FlowyIconButton( + hoverColor: theme.hover, + width: 22, + onPressed: () => context.read().add(const RowEvent.createRow()), + icon: svg("home/add"), ), ); } } + +class DrawRowButton extends StatelessWidget { + const DrawRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 4d5da03423..c251546cce 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,62 +1,56 @@ -import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; import 'grid_cell.dart'; - -class GridRowContext { - final RepeatedFieldOrder fieldOrders; - final Map fieldById; - final Map cellByFieldId; - GridRowContext(this.fieldOrders, this.fieldById, this.cellByFieldId); -} +import 'package:dartz/dartz.dart'; class GridRowWidget extends StatelessWidget { - final RowInfo rowInfo; + final GridRowData data; final Function(bool)? onHoverChange; - const GridRowWidget(this.rowInfo, {Key? key, this.onHoverChange}) : super(key: key); + const GridRowWidget(this.data, {Key? key, this.onHoverChange}) : super(key: key); @override Widget build(BuildContext context) { - return SizedBox( - height: GridSize.rowHeight, - child: _buildRowBody(), + return BlocProvider( + create: (context) => getIt(param1: data), + child: BlocBuilder( + builder: (context, state) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => context.read().add(RowEvent.highlightRow(some(data.row.id))), + onExit: (p) => context.read().add(RowEvent.highlightRow(none())), + child: SizedBox( + height: data.row.height.toDouble(), + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: _buildCells(), + ), + ), + ), + ); + }, + ), ); } - Widget _buildRowBody() { - Widget rowWidget = Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: _buildCells(), - ); - - if (onHoverChange != null) { - rowWidget = MouseRegion( - onEnter: (event) => onHoverChange!(true), - onExit: (event) => onHoverChange!(false), - cursor: MouseCursor.uncontrolled, - child: rowWidget, - ); - } - - return rowWidget; - } - List _buildCells() { - var cells = List.empty(growable: true); - cells.add(const RowLeading()); - - for (var field in rowInfo.fields) { - final data = rowInfo.cellMap[field.id]; - final cell = CellContainer( - width: field.width.toDouble(), - child: GridCellBuilder.buildCell(field, data), - ); - - cells.add(cell); - } - return cells; + return [ + RowLeading(rowId: data.row.id), + ...data.fields.map( + (field) { + final cellData = data.cellMap[field.id]; + return CellContainer( + width: field.width.toDouble(), + child: GridCellBuilder.buildCell(field, cellData), + ); + }, + ) + ].toList(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index cdbb0d6e51..6e1befe18e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -34,7 +34,7 @@ class AddRowButton extends StatelessWidget { onTap: onTap, child: MouseHoverBuilder( builder: (_, isHovered) => Container( - width: GridSize.firstHeaderPadding, + width: GridSize.startHeaderPadding, height: GridSize.footerHeight, decoration: CellDecoration.box( color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 4148f1e041..ca59069f3f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -45,7 +45,7 @@ class HeaderCellLeading extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - width: GridSize.firstHeaderPadding, + width: GridSize.startHeaderPadding, color: GridHeaderConstants.backgroundColor, ); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 102be7fb09..6fd298b16d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -550,6 +550,7 @@ class RawRow extends $pb.GeneratedMessage { ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..m<$core.String, RawCell>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RawRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: RawCell.create) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -558,6 +559,7 @@ class RawRow extends $pb.GeneratedMessage { $core.String? id, $core.String? gridId, $core.Map<$core.String, RawCell>? cellByFieldId, + $core.int? height, }) { final _result = create(); if (id != null) { @@ -569,6 +571,9 @@ class RawRow extends $pb.GeneratedMessage { if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); } + if (height != null) { + _result.height = height; + } return _result; } factory RawRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -612,6 +617,15 @@ class RawRow extends $pb.GeneratedMessage { @$pb.TagNumber(3) $core.Map<$core.String, RawCell> get cellByFieldId => $_getMap(2); + + @$pb.TagNumber(4) + $core.int get height => $_getIZ(3); + @$pb.TagNumber(4) + set height($core.int v) { $_setSignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasHeight() => $_has(3); + @$pb.TagNumber(4) + void clearHeight() => clearField(4); } class RawCell extends $pb.GeneratedMessage { @@ -620,6 +634,7 @@ class RawCell extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) + ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -629,6 +644,7 @@ class RawCell extends $pb.GeneratedMessage { $core.String? rowId, $core.String? fieldId, AnyData? data, + $core.int? height, }) { final _result = create(); if (id != null) { @@ -643,6 +659,9 @@ class RawCell extends $pb.GeneratedMessage { if (data != null) { _result.data = data; } + if (height != null) { + _result.height = height; + } return _result; } factory RawCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -703,6 +722,15 @@ class RawCell extends $pb.GeneratedMessage { void clearData() => clearField(4); @$pb.TagNumber(4) AnyData ensureData() => $_ensure(3); + + @$pb.TagNumber(5) + $core.int get height => $_getIZ(4); + @$pb.TagNumber(5) + set height($core.int v) { $_setSignedInt32(4, v); } + @$pb.TagNumber(5) + $core.bool hasHeight() => $_has(4); + @$pb.TagNumber(5) + void clearHeight() => clearField(5); } class RepeatedRow extends $pb.GeneratedMessage { @@ -750,6 +778,7 @@ class Row extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Row', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..m<$core.String, Cell>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'Row.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: Cell.create) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -757,6 +786,7 @@ class Row extends $pb.GeneratedMessage { factory Row({ $core.String? id, $core.Map<$core.String, Cell>? cellByFieldId, + $core.int? height, }) { final _result = create(); if (id != null) { @@ -765,6 +795,9 @@ class Row extends $pb.GeneratedMessage { if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); } + if (height != null) { + _result.height = height; + } return _result; } factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -799,6 +832,15 @@ class Row extends $pb.GeneratedMessage { @$pb.TagNumber(2) $core.Map<$core.String, Cell> get cellByFieldId => $_getMap(1); + + @$pb.TagNumber(3) + $core.int get height => $_getIZ(2); + @$pb.TagNumber(3) + set height($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasHeight() => $_has(2); + @$pb.TagNumber(3) + void clearHeight() => clearField(3); } class Cell extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 9a97445271..81257592ac 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -122,6 +122,7 @@ const RawRow$json = const { const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RawRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, ], '3': const [RawRow_CellByFieldIdEntry$json], }; @@ -137,7 +138,7 @@ const RawRow_CellByFieldIdEntry$json = const { }; /// Descriptor for `RawRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); +final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBIWCgZoZWlnaHQYBCABKAVSBmhlaWdodBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); @$core.Deprecated('Use rawCellDescriptor instead') const RawCell$json = const { '1': 'RawCell', @@ -146,11 +147,12 @@ const RawCell$json = const { const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, + const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, ], }; /// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRh'); +final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRhEhYKBmhlaWdodBgFIAEoBVIGaGVpZ2h0'); @$core.Deprecated('Use repeatedRowDescriptor instead') const RepeatedRow$json = const { '1': 'RepeatedRow', @@ -167,6 +169,7 @@ const Row$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'cell_by_field_id', '3': 2, '4': 3, '5': 11, '6': '.Row.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'height', '3': 3, '4': 1, '5': 5, '10': 'height'}, ], '3': const [Row_CellByFieldIdEntry$json], }; @@ -182,7 +185,7 @@ const Row_CellByFieldIdEntry$json = const { }; /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs index e67d9176cd..1bce574abb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -3,7 +3,6 @@ use flowy_collaboration::client_grid::make_grid_delta; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawCell, RawRow, RowOrder}; use lib_infra::uuid; -use std::collections::HashMap; use std::sync::Arc; pub struct GridBuilder { @@ -24,40 +23,19 @@ impl GridBuilder { } pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { - let field = Field { - id: uuid(), - name: name.to_string(), - desc: desc.to_string(), - field_type, - frozen: false, - width: 100, - type_options: Default::default(), - }; + let field = Field::new(&uuid(), name, desc, field_type); self.fields.push(field); self } pub fn add_empty_row(mut self) -> Self { - let row = RawRow { - id: uuid(), - grid_id: self.grid_id.clone(), - cell_by_field_id: Default::default(), - }; + let row = RawRow::new(&uuid(), &self.grid_id, vec![]); self.rows.push(row); self } pub fn add_row(mut self, cells: Vec) -> Self { - let cell_by_field_id = cells - .into_iter() - .map(|cell| (cell.id.clone(), cell)) - .collect::>(); - - let row = RawRow { - id: uuid(), - grid_id: self.grid_id.clone(), - cell_by_field_id, - }; + let row = RawRow::new(&uuid(), &self.grid_id, cells); self.rows.push(row); self } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 418807e058..9512e59b26 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -56,11 +56,7 @@ impl ClientGridEditor { } pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RawRow { - id: uuid(), - grid_id: self.grid_id.clone(), - cell_by_field_id: Default::default(), - }; + let row = RawRow::new(&uuid(), &self.grid_id, vec![]); self.create_row(row).await?; Ok(()) } @@ -121,7 +117,11 @@ impl ClientGridEditor { let rows = raw_rows .into_par_iter() .map(|raw_row| { - let mut row = Row::new(&raw_row.id); + let mut row = Row { + id: raw_row.id.clone(), + cell_by_field_id: Default::default(), + height: raw_row.height, + }; row.cell_by_field_id = raw_row .cell_by_field_id .into_par_iter() diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 926ca1e750..f8b616c22a 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -3,6 +3,9 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{Display, EnumIter, EnumString}; +pub const DEFAULT_ROW_HEIGHT: i32 = 36; +pub const DEFAULT_FIELD_WIDTH: i32 = 150; + pub trait GridIdentifiable { fn id(&self) -> &str; } @@ -90,6 +93,20 @@ pub struct Field { pub type_options: AnyData, } +impl Field { + pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { + Self { + id: id.to_owned(), + name: name.to_string(), + desc: desc.to_string(), + field_type, + frozen: false, + width: DEFAULT_FIELD_WIDTH, + type_options: Default::default(), + } + } +} + impl GridIdentifiable for Field { fn id(&self) -> &str { &self.id @@ -245,6 +262,25 @@ pub struct RawRow { #[pb(index = 3)] pub cell_by_field_id: HashMap, + + #[pb(index = 4)] + pub height: i32, +} + +impl RawRow { + pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { + let cell_by_field_id = cells + .into_iter() + .map(|cell| (cell.id.clone(), cell)) + .collect::>(); + + Self { + id: id.to_owned(), + grid_id: grid_id.to_owned(), + cell_by_field_id, + height: DEFAULT_ROW_HEIGHT, + } + } } impl GridIdentifiable for RawRow { @@ -266,6 +302,9 @@ pub struct RawCell { #[pb(index = 4)] pub data: AnyData, + + #[pb(index = 5)] + pub height: i32, } #[derive(Debug, Default, ProtoBuf)] @@ -300,15 +339,9 @@ pub struct Row { #[pb(index = 2)] pub cell_by_field_id: HashMap, -} -impl Row { - pub fn new(row_id: &str) -> Self { - Self { - id: row_id.to_owned(), - cell_by_field_id: HashMap::new(), - } - } + #[pb(index = 3)] + pub height: i32, } #[derive(Debug, Default, ProtoBuf)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index f64dde24e6..b1a732e42e 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -1832,6 +1832,7 @@ pub struct RawRow { pub id: ::std::string::String, pub grid_id: ::std::string::String, pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, RawCell>, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1924,6 +1925,21 @@ impl RawRow { pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, RawCell> { ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) } + + // int32 height = 4; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for RawRow { @@ -1944,6 +1960,13 @@ impl ::protobuf::Message for RawRow { 3 => { ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1963,6 +1986,9 @@ impl ::protobuf::Message for RawRow { my_size += ::protobuf::rt::string_size(2, &self.grid_id); } my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); + if self.height != 0 { + my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -1976,6 +2002,9 @@ impl ::protobuf::Message for RawRow { os.write_string(2, &self.grid_id)?; } ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; + if self.height != 0 { + os.write_int32(4, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2029,6 +2058,11 @@ impl ::protobuf::Message for RawRow { |m: &RawRow| { &m.cell_by_field_id }, |m: &mut RawRow| { &mut m.cell_by_field_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RawRow| { &m.height }, + |m: &mut RawRow| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RawRow", fields, @@ -2048,6 +2082,7 @@ impl ::protobuf::Clear for RawRow { self.id.clear(); self.grid_id.clear(); self.cell_by_field_id.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -2071,6 +2106,7 @@ pub struct RawCell { pub row_id: ::std::string::String, pub field_id: ::std::string::String, pub data: ::protobuf::SingularPtrField, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2197,6 +2233,21 @@ impl RawCell { pub fn take_data(&mut self) -> AnyData { self.data.take().unwrap_or_else(|| AnyData::new()) } + + // int32 height = 5; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for RawCell { @@ -2225,6 +2276,13 @@ impl ::protobuf::Message for RawCell { 4 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -2250,6 +2308,9 @@ impl ::protobuf::Message for RawCell { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2270,6 +2331,9 @@ impl ::protobuf::Message for RawCell { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } + if self.height != 0 { + os.write_int32(5, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2328,6 +2392,11 @@ impl ::protobuf::Message for RawCell { |m: &RawCell| { &m.data }, |m: &mut RawCell| { &mut m.data }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RawCell| { &m.height }, + |m: &mut RawCell| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RawCell", fields, @@ -2348,6 +2417,7 @@ impl ::protobuf::Clear for RawCell { self.row_id.clear(); self.field_id.clear(); self.data.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -2535,6 +2605,7 @@ pub struct Row { // message fields pub id: ::std::string::String, pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, Cell>, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2601,6 +2672,21 @@ impl Row { pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, Cell> { ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) } + + // int32 height = 3; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for Row { @@ -2618,6 +2704,13 @@ impl ::protobuf::Message for Row { 2 => { ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -2634,6 +2727,9 @@ impl ::protobuf::Message for Row { my_size += ::protobuf::rt::string_size(1, &self.id); } my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.cell_by_field_id); + if self.height != 0 { + my_size += ::protobuf::rt::value_size(3, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2644,6 +2740,9 @@ impl ::protobuf::Message for Row { os.write_string(1, &self.id)?; } ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.cell_by_field_id, os)?; + if self.height != 0 { + os.write_int32(3, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2692,6 +2791,11 @@ impl ::protobuf::Message for Row { |m: &Row| { &m.cell_by_field_id }, |m: &mut Row| { &mut m.cell_by_field_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &Row| { &m.height }, + |m: &mut Row| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Row", fields, @@ -2710,6 +2814,7 @@ impl ::protobuf::Clear for Row { fn clear(&mut self) { self.id.clear(); self.cell_by_field_id.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -4085,35 +4190,37 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ \x20\x01(\tR\x05rowId\x12\x1e\n\nvisibility\x18\x03\x20\x01(\x08R\nvisib\ ility\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\ - \t.RowOrderR\x05items\"\xc2\x01\n\x06RawRow\x12\x0e\n\x02id\x18\x01\x20\ + \t.RowOrderR\x05items\"\xda\x01\n\x06RawRow\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12C\n\ \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1a.RawRow.CellByFieldIdEntry\ - R\rcellByFieldId\x1aJ\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCell\ - R\x05value:\x028\x01\"i\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ - ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\ - \x0b2\x08.AnyDataR\x04data\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ - \x01\x20\x03(\x0b2\x04.RowR\x05items\"\xa0\x01\n\x03Row\x12\x0e\n\x02id\ - \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\ - \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldId\ - Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ - \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"K\n\x04Cell\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\ - \tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"e\n\ - \rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06r\ - ow_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01\ - (\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\x01(\tR\x04data\"'\n\x11Cr\ - eateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\ - \x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11Query\ - FieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\ - \x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldO\ - rders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrder\ - R\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Numbe\ - r\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ - \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ - proto3\ + R\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\x1a\ + J\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\ + \x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCellR\x05value:\x028\ + \x01\"\x81\x01\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ + \x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\ + \x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06heigh\ + t\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\ + \x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdE\ + ntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\ + \x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03ke\ + y\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\ + \"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08fie\ + ld_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\ + \x01(\tR\x07content\"e\n\rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ + field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\ + \x01(\tR\x04data\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\ + \x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\t\ + R\x05value\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.Repe\ + atedFieldOrderR\x0bfieldOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07gri\ + d_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\ + \x0b2\x11.RepeatedRowOrderR\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichT\ + ext\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\ + \x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\ + \n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 79d6af77e1..04e82bea78 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -40,12 +40,14 @@ message RawRow { string id = 1; string grid_id = 2; map cell_by_field_id = 3; + int32 height = 4; } message RawCell { string id = 1; string row_id = 2; string field_id = 3; AnyData data = 4; + int32 height = 5; } message RepeatedRow { repeated Row items = 1; @@ -53,6 +55,7 @@ message RepeatedRow { message Row { string id = 1; map cell_by_field_id = 2; + int32 height = 3; } message Cell { string id = 1; From 808d848f621f6efbbf8f613d7b3bd38da467f656 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 8 Mar 2022 22:58:43 +0800 Subject: [PATCH 022/179] feat: cell border --- .../src/widgets/content/cell_container.dart | 8 ++++ .../grid/src/widgets/content/grid_cell.dart | 17 +-------- .../grid/src/widgets/content/grid_row.dart | 3 +- .../grid/src/widgets/header/header.dart | 4 +- .../grid/src/widgets/header/header_cell.dart | 38 +++++++++++-------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 03f0e82115..5b771b8c92 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,5 +1,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/theme.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class CellContainer extends StatelessWidget { final Widget child; @@ -12,6 +14,9 @@ class CellContainer extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () {}, @@ -19,6 +24,9 @@ class CellContainer extends StatelessWidget { constraints: BoxConstraints( maxWidth: width, ), + decoration: BoxDecoration( + border: Border(right: borderSide, bottom: borderSide), + ), padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), child: Center(child: IntrinsicHeight(child: child)), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 5c0dbabfea..5646376bf7 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -102,27 +102,14 @@ class RowLeading extends StatelessWidget { return Row( children: const [ CreateRowButton(), + DrawRowButton(), ], ); } - return const Spacer(); + return const SizedBox.expand(); }, ); - - // return GestureDetector( - // behavior: HitTestBehavior.translucent, - // onTap: () {}, - // child: MouseHoverBuilder( - // builder: (_, isHovered) => Container( - // width: GridSize.startHeaderPadding, - // decoration: CellDecoration.box( - // color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, - // ), - // padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - // ), - // ), - // ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index c251546cce..3ef343493a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -41,7 +42,7 @@ class GridRowWidget extends StatelessWidget { List _buildCells() { return [ - RowLeading(rowId: data.row.id), + SizedBox(width: GridSize.startHeaderPadding, child: RowLeading(rowId: data.row.id)), ...data.fields.map( (field) { final cellData = data.cellMap[field.id]; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 9f894f8ee5..c70d3ce3b2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -40,9 +40,7 @@ class GridHeader extends StatelessWidget { fields.asMap().forEach((index, field) { final header = HeaderCellContainer( width: field.width.toDouble(), - child: HeaderCell( - field, - ), + child: HeaderCell(field), ); // diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index ca59069f3f..e059208aff 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,6 +1,10 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'constants.dart'; class HeaderCell extends StatelessWidget { @@ -9,10 +13,16 @@ class HeaderCell extends StatelessWidget { @override Widget build(BuildContext context) { - return Text( - field.name, - style: const TextStyle(fontSize: 15.0, color: Colors.black), + final theme = context.watch(); + return FlowyButton( + text: FlowyText.medium(field.name), + hoverColor: theme.hover, + onTap: () {}, ); + // return Text( + // field.name, + // style: const TextStyle(fontSize: 15.0, color: Colors.black), + // ); } } @@ -23,18 +33,15 @@ class HeaderCellContainer extends StatelessWidget { @override Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () {}, - child: Container( - width: width, - decoration: BoxDecoration( - border: Border.all(color: Colors.black26, width: 0.5), - color: GridHeaderConstants.backgroundColor, - ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - child: child, + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return Container( + width: width, + decoration: BoxDecoration( + border: Border(top: borderSide, right: borderSide, bottom: borderSide), ), + padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + child: child, ); } } @@ -44,9 +51,8 @@ class HeaderCellLeading extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( + return SizedBox( width: GridSize.startHeaderPadding, - color: GridHeaderConstants.backgroundColor, ); } } From 00db755c29355aca7e3d40cf80ebd26c4e40394d Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 9 Mar 2022 09:31:06 +0800 Subject: [PATCH 023/179] feat: add cloumn bloc --- .../lib/startup/home_deps_resolver.dart | 8 ++ .../application/grid/column_bloc.dart | 43 +++++++++ .../application/grid/column_service.dart | 1 + .../lib/workspace/application/grid/data.dart | 6 ++ .../workspace/application/grid/prelude.dart | 2 + .../plugins/grid/src/grid_page.dart | 10 +-- .../plugins/grid/src/layout/layout.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 30 +++++-- .../src/widgets/content/cell_container.dart | 2 +- .../grid/src/widgets/content/grid_cell.dart | 61 ------------- .../grid/src/widgets/content/grid_row.dart | 74 ++++++++++++++- .../grid/src/widgets/footer/grid_footer.dart | 46 +++++----- .../grid/src/widgets/header/header.dart | 90 +++++++++++++++---- .../grid/src/widgets/header/header_cell.dart | 16 +--- .../lib/style_widget/button.dart | 2 +- 15 files changed, 255 insertions(+), 138 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_service.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 9a2a47301e..54275b95b3 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -12,6 +12,7 @@ import 'package:app_flowy/workspace/application/menu/prelude.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -102,6 +103,13 @@ class HomeDepsResolver { ), ); + getIt.registerFactoryParam, void>( + (data, _) => ColumnBloc( + data: GridColumnData(fields: data), + service: ColumnService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart new file mode 100644 index 0000000000..844360fa9b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -0,0 +1,43 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:dartz/dartz.dart'; +import 'dart:async'; +import 'column_service.dart'; +import 'data.dart'; + +part 'column_bloc.freezed.dart'; + +class ColumnBloc extends Bloc { + final ColumnService service; + final GridColumnData data; + + ColumnBloc({required this.data, required this.service}) : super(ColumnState.initial(data.fields)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialColumn value) async {}, + createColumn: (_CreateColumn value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class ColumnEvent with _$ColumnEvent { + const factory ColumnEvent.initial() = _InitialColumn; + const factory ColumnEvent.createColumn() = _CreateColumn; +} + +@freezed +abstract class ColumnState with _$ColumnState { + const factory ColumnState({required List fields}) = _ColumnState; + + factory ColumnState.initial(List fields) => ColumnState(fields: fields); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_service.dart b/frontend/app_flowy/lib/workspace/application/grid/column_service.dart new file mode 100644 index 0000000000..c074dcf616 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/column_service.dart @@ -0,0 +1 @@ +class ColumnService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 6c815b7f35..b0e260fe8e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -33,3 +33,9 @@ class GridRowData { required this.cellMap, }); } + +class GridColumnData { + final List fields; + + GridColumnData({required this.fields}); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index bf48b7cc8b..3cbe922a58 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -3,3 +3,5 @@ export 'row_bloc.dart'; export 'row_service.dart'; export 'grid_service.dart'; export 'data.dart'; +export 'column_service.dart'; +export 'column_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index ae3934b7cb..ba89c63662 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -111,7 +111,7 @@ class _GridBodyState extends State { slivers: [ _buildHeader(gridInfo.fields), _buildRows(gridInfo), - _builderFooter(context), + const GridFooter(), ], ), ), @@ -145,12 +145,4 @@ class _GridBodyState extends State { ), ); } - - Widget _builderFooter(BuildContext context) { - return GridFooter( - onAddRow: () { - context.read().add(const GridEvent.createRow()); - }, - ); - } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 5b58d3c1c5..3f076fc89f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -8,6 +8,6 @@ class GridLayout { final fieldsWidth = fields.map((field) => field.width.toDouble()).reduce((value, element) => value + element); - return fieldsWidth + GridSize.startHeaderPadding; + return fieldsWidth + GridSize.leadingHeaderPadding + GridSize.trailHeaderPadding; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index e577311200..e669a78217 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -1,15 +1,29 @@ -class GridInsets { - static double scale = 1; - - static double get horizontal => 8 * scale; - static double get vertical => 8 * scale; -} +import 'package:flutter/widgets.dart'; class GridSize { static double scale = 1; static double get scrollBarSize => 12 * scale; - static double get headerHeight => 50 * scale; + static double get headerHeight => 40 * scale; static double get footerHeight => 40 * scale; - static double get startHeaderPadding => 30 * scale; + static double get leadingHeaderPadding => 30 * scale; + static double get trailHeaderPadding => 140 * scale; + static double get headerContentPadding => 8 * scale; + static double get cellContentPadding => 8 * scale; + // + static EdgeInsets get headerContentInsets => EdgeInsets.symmetric( + horizontal: GridSize.headerContentPadding, + vertical: GridSize.headerContentPadding, + ); + static EdgeInsets get cellContentInsets => EdgeInsets.symmetric( + horizontal: GridSize.cellContentPadding, + vertical: GridSize.cellContentPadding, + ); + + static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( + 0, + GridSize.headerContentPadding, + GridSize.headerContentPadding, + GridSize.headerContentPadding, + ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 5b771b8c92..0fbdc3b53c 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -27,7 +27,7 @@ class CellContainer extends StatelessWidget { decoration: BoxDecoration( border: Border(right: borderSide, bottom: borderSide), ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + padding: GridSize.cellContentInsets, child: Center(child: IntrinsicHeight(child: child)), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 5646376bf7..be04555bd4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -1,15 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; -import 'package:app_flowy/workspace/presentation/home/menu/app/header/add_button.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/icon_button.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import 'cell_decoration.dart'; -// ignore: import_of_legacy_library_into_null_safe /// The interface of base cell. abstract class GridCellWidget extends StatelessWidget { @@ -89,53 +78,3 @@ class BlankCell extends GridCellWidget { return Container(); } } - -class RowLeading extends StatelessWidget { - final String rowId; - const RowLeading({required this.rowId, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state.isHighlight) { - return Row( - children: const [ - CreateRowButton(), - DrawRowButton(), - ], - ); - } - - return const SizedBox.expand(); - }, - ); - } -} - -class CreateRowButton extends StatelessWidget { - const CreateRowButton({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return Tooltip( - message: '', - child: FlowyIconButton( - hoverColor: theme.hover, - width: 22, - onPressed: () => context.read().add(const RowEvent.createRow()), - icon: svg("home/add"), - ), - ); - } -} - -class DrawRowButton extends StatelessWidget { - const DrawRowButton({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container(); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 3ef343493a..3e43d4fd8d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,7 +1,9 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; @@ -42,7 +44,10 @@ class GridRowWidget extends StatelessWidget { List _buildCells() { return [ - SizedBox(width: GridSize.startHeaderPadding, child: RowLeading(rowId: data.row.id)), + SizedBox( + width: GridSize.leadingHeaderPadding, + child: LeadingRow(rowId: data.row.id), + ), ...data.fields.map( (field) { final cellData = data.cellMap[field.id]; @@ -51,7 +56,72 @@ class GridRowWidget extends StatelessWidget { child: GridCellBuilder.buildCell(field, cellData), ); }, + ), + SizedBox( + width: GridSize.trailHeaderPadding, + child: TrailingRow(rowId: data.row.id), ) ].toList(); } } + +class LeadingRow extends StatelessWidget { + final String rowId; + const LeadingRow({required this.rowId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state.isHighlight) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + CreateRowButton(), + ], + ); + } + return const SizedBox.expand(); + }, + ); + } +} + +class TrailingRow extends StatelessWidget { + final String rowId; + const TrailingRow({required this.rowId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + + return BlocBuilder( + builder: (context, state) { + return Container( + width: GridSize.trailHeaderPadding, + decoration: BoxDecoration( + border: Border(bottom: borderSide), + ), + padding: GridSize.cellContentInsets, + ); + }, + ); + } +} + +class CreateRowButton extends StatelessWidget { + const CreateRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyIconButton( + hoverColor: theme.hover, + width: 22, + onPressed: () => context.read().add(const RowEvent.createRow()), + iconPadding: const EdgeInsets.all(3), + icon: svg("home/add"), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 6e1befe18e..5ca3bf0f6b 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -1,22 +1,28 @@ +import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; - -import '../content/cell_decoration.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class GridFooter extends StatelessWidget { - final VoidCallback? onAddRow; - const GridFooter({Key? key, required this.onAddRow}) : super(key: key); + const GridFooter({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return SliverToBoxAdapter( child: SizedBox( height: GridSize.footerHeight, - child: Row( - children: [ - AddRowButton(onTap: onAddRow), - ], + child: Padding( + padding: GridSize.headerContentInsets, + child: Row( + children: [ + SizedBox(width: GridSize.leadingHeaderPadding), + const SizedBox(width: 120, child: AddRowButton()), + ], + ), ), ), ); @@ -24,24 +30,16 @@ class GridFooter extends StatelessWidget { } class AddRowButton extends StatelessWidget { - final VoidCallback? onTap; - const AddRowButton({Key? key, required this.onTap}) : super(key: key); + const AddRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: onTap, - child: MouseHoverBuilder( - builder: (_, isHovered) => Container( - width: GridSize.startHeaderPadding, - height: GridSize.footerHeight, - decoration: CellDecoration.box( - color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, - ), - child: const Icon(Icons.add, size: 16), - ), - ), + final theme = context.watch(); + return FlowyButton( + text: const FlowyText.medium('New row', fontSize: 12), + hoverColor: theme.hover, + onTap: () => context.read().add(const RowEvent.createRow()), + icon: svg("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index c70d3ce3b2..d3cf4a5255 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -1,6 +1,13 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/column_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'header_cell.dart'; @@ -31,28 +38,77 @@ class GridHeaderDelegate extends SliverPersistentHeaderDelegate { class GridHeader extends StatelessWidget { final List fields; - const GridHeader({required this.fields, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final headers = List.empty(growable: true); - fields.asMap().forEach((index, field) { - final header = HeaderCellContainer( - width: field.width.toDouble(), - child: HeaderCell(field), - ); + return BlocProvider( + create: (context) => getIt(param1: fields), + child: BlocBuilder( + builder: (context, state) { + final headers = state.fields + .map( + (field) => HeaderCellContainer( + width: field.width.toDouble(), + child: HeaderCell(field), + ), + ) + .toList(); - // - headers.add(header); - }); - - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const HeaderCellLeading(), - ...headers, - ], + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingHeaderCell(), + ...headers, + const TrailingHeaderCell(), + ], + ); + }, + ), + ); + } +} + +class LeadingHeaderCell extends StatelessWidget { + const LeadingHeaderCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: GridSize.leadingHeaderPadding, + ); + } +} + +class TrailingHeaderCell extends StatelessWidget { + const TrailingHeaderCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return Container( + width: GridSize.trailHeaderPadding, + decoration: BoxDecoration( + border: Border(top: borderSide, bottom: borderSide), + ), + padding: GridSize.headerContentInsets, + child: const CreateColumnButton(), + ); + } +} + +class CreateColumnButton extends StatelessWidget { + const CreateColumnButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: const FlowyText.medium('New column', fontSize: 12), + hoverColor: theme.hover, + onTap: () => context.read().add(const ColumnEvent.createColumn()), + icon: svg("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index e059208aff..9b77af4b3e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -5,7 +5,6 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'constants.dart'; class HeaderCell extends StatelessWidget { final Field field; @@ -15,7 +14,7 @@ class HeaderCell extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( - text: FlowyText.medium(field.name), + text: FlowyText.medium(field.name, fontSize: 12), hoverColor: theme.hover, onTap: () {}, ); @@ -40,19 +39,8 @@ class HeaderCellContainer extends StatelessWidget { decoration: BoxDecoration( border: Border(top: borderSide, right: borderSide, bottom: borderSide), ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + padding: GridSize.headerContentInsets, child: child, ); } } - -class HeaderCellLeading extends StatelessWidget { - const HeaderCellLeading({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - width: GridSize.startHeaderPadding, - ); - } -} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 6b67081ca2..b7d8ea4e88 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -24,7 +24,7 @@ class FlowyButton extends StatelessWidget { return InkWell( onTap: onTap, child: FlowyHover( - config: HoverDisplayConfig(borderRadius: Corners.s6Border, hoverColor: hoverColor), + config: HoverDisplayConfig(borderRadius: Corners.s5Border, hoverColor: hoverColor), builder: (context, onHover) => _render(), ), ); From 321682717cbe4f01ca362331792d4f0dd12a62c1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 9 Mar 2022 12:11:27 +0800 Subject: [PATCH 024/179] chore: opti row rebuild --- .../lib/workspace/application/grid/data.dart | 14 +- .../workspace/application/grid/row_bloc.dart | 23 +-- .../plugins/grid/src/grid_page.dart | 2 +- .../src/widgets/content/cell_container.dart | 13 +- .../grid/src/widgets/content/grid_row.dart | 133 ++++++++++-------- .../grid/src/widgets/header/header_cell.dart | 4 - 6 files changed, 105 insertions(+), 84 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index b0e260fe8e..c32f87f1a2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:equatable/equatable.dart'; class GridInfo { List rows; @@ -23,15 +24,18 @@ class GridInfo { } } -class GridRowData { - Row row; - List fields; - Map cellMap; - GridRowData({ +class GridRowData extends Equatable { + final Row row; + final List fields; + final Map cellMap; + const GridRowData({ required this.row, required this.fields, required this.cellMap, }); + + @override + List get props => [row.hashCode, cellMap]; } class GridColumnData { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 8feb26e4c7..9af22beba9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -1,6 +1,5 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:dartz/dartz.dart'; import 'dart:async'; import 'data.dart'; import 'row_service.dart'; @@ -9,18 +8,18 @@ part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { final RowService service; - final GridRowData data; - RowBloc({required this.data, required this.service}) : super(RowState.initial()) { + RowBloc({required GridRowData data, required this.service}) : super(RowState.initial(data)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async {}, createRow: (_CreateRow value) {}, - highlightRow: (_HighlightRow value) { - emit(state.copyWith( - isHighlight: value.rowId.fold(() => false, (rowId) => rowId == data.row.id), - )); + activeRow: (_ActiveRow value) { + emit(state.copyWith(active: true)); + }, + disactiveRow: (_DisactiveRow value) { + emit(state.copyWith(active: false)); }, ); }, @@ -35,16 +34,18 @@ class RowBloc extends Bloc { @freezed abstract class RowEvent with _$RowEvent { - const factory RowEvent.initial() = _InitialRow; + const factory RowEvent.initial(GridRowData data) = _InitialRow; const factory RowEvent.createRow() = _CreateRow; - const factory RowEvent.highlightRow(Option rowId) = _HighlightRow; + const factory RowEvent.activeRow() = _ActiveRow; + const factory RowEvent.disactiveRow() = _DisactiveRow; } @freezed abstract class RowState with _$RowState { const factory RowState({ - required bool isHighlight, + required GridRowData data, + required bool active, }) = _RowState; - factory RowState.initial() => const RowState(isHighlight: false); + factory RowState.initial(GridRowData data) => RowState(data: data, active: false); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index ba89c63662..7435ea0e5f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -139,7 +139,7 @@ class _GridBodyState extends State { delegate: SliverChildBuilderDelegate( (context, index) { final data = gridInfo.rowAtIndex(index); - return RepaintBoundary(child: GridRowWidget(data)); + return RepaintBoundary(child: GridRowWidget(data: data)); }, childCount: gridInfo.numberOfRows(), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 0fbdc3b53c..56cc4e174f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,9 +1,10 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class CellContainer extends StatelessWidget { +class CellContainer extends StatefulWidget { final Widget child; final double width; const CellContainer({ @@ -12,23 +13,27 @@ class CellContainer extends StatelessWidget { required this.width, }) : super(key: key); + @override + State createState() => _CellContainerState(); +} + +class _CellContainerState extends State { @override Widget build(BuildContext context) { final theme = context.watch(); final borderSide = BorderSide(color: theme.shader4, width: 0.4); - return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () {}, child: Container( constraints: BoxConstraints( - maxWidth: width, + maxWidth: widget.width, ), decoration: BoxDecoration( border: Border(right: borderSide, bottom: borderSide), ), padding: GridSize.cellContentInsets, - child: Center(child: IntrinsicHeight(child: child)), + child: Center(child: IntrinsicHeight(child: widget.child)), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 3e43d4fd8d..dce4b61d4f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -8,88 +8,103 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; -import 'grid_cell.dart'; -import 'package:dartz/dartz.dart'; -class GridRowWidget extends StatelessWidget { +class GridRowWidget extends StatefulWidget { final GridRowData data; - final Function(bool)? onHoverChange; - const GridRowWidget(this.data, {Key? key, this.onHoverChange}) : super(key: key); + GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.row.id)); + + @override + State createState() => _GridRowWidgetState(); +} + +class _GridRowWidgetState extends State { + late RowBloc _rowBloc; + + @override + void initState() { + _rowBloc = getIt(param1: widget.data); + super.initState(); + } @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: data), - child: BlocBuilder( - builder: (context, state) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => context.read().add(RowEvent.highlightRow(some(data.row.id))), - onExit: (p) => context.read().add(RowEvent.highlightRow(none())), - child: SizedBox( - height: data.row.height.toDouble(), - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: _buildCells(), - ), - ), + return BlocProvider.value( + value: _rowBloc, + child: GestureDetector( + behavior: HitTestBehavior.translucent, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + child: SizedBox( + height: _rowBloc.state.data.row.height.toDouble(), + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingRow(), + _buildCells(), + const TrailingRow(), + ], ), - ); - }, + ), + ), ), ); } - List _buildCells() { - return [ - SizedBox( - width: GridSize.leadingHeaderPadding, - child: LeadingRow(rowId: data.row.id), - ), - ...data.fields.map( - (field) { - final cellData = data.cellMap[field.id]; - return CellContainer( - width: field.width.toDouble(), - child: GridCellBuilder.buildCell(field, cellData), - ); - }, - ), - SizedBox( - width: GridSize.trailHeaderPadding, - child: TrailingRow(rowId: data.row.id), - ) - ].toList(); + @override + Future dispose() async { + _rowBloc.close(); + super.dispose(); + } + + Widget _buildCells() { + return BlocBuilder( + buildWhen: (p, c) => p.data != c.data, + builder: (context, state) { + return Row( + key: ValueKey(state.data.row.id), + children: state.data.fields.map( + (field) { + final cellData = state.data.cellMap[field.id]; + return CellContainer( + width: field.width.toDouble(), + child: GridCellBuilder.buildCell(field, cellData), + ); + }, + ).toList(), + ); + }, + ); } } class LeadingRow extends StatelessWidget { - final String rowId; - const LeadingRow({required this.rowId, Key? key}) : super(key: key); + const LeadingRow({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state.isHighlight) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - CreateRowButton(), - ], - ); - } - return const SizedBox.expand(); + return BlocSelector( + selector: (state) => state.active, + builder: (context, isActive) { + return SizedBox( + width: GridSize.leadingHeaderPadding, + child: isActive + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + CreateRowButton(), + ], + ) + : null, + ); }, ); } } class TrailingRow extends StatelessWidget { - final String rowId; - const TrailingRow({required this.rowId, Key? key}) : super(key: key); + const TrailingRow({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 9b77af4b3e..aacdcd251e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -18,10 +18,6 @@ class HeaderCell extends StatelessWidget { hoverColor: theme.hover, onTap: () {}, ); - // return Text( - // field.name, - // style: const TextStyle(fontSize: 15.0, color: Colors.black), - // ); } } From fe8811392b79332274cae91fa6535bb58baf75f9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 9 Mar 2022 16:11:24 +0800 Subject: [PATCH 025/179] feat: config cells --- .../lib/startup/home_deps_resolver.dart | 40 ++++++++++ .../grid/cell_bloc/cell_service.dart | 1 + .../grid/cell_bloc/checkbox_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/date_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/number_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/selection_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/text_cell_bloc.dart | 48 +++++++++++ .../application/grid/column_bloc.dart | 1 - .../workspace/application/grid/prelude.dart | 6 ++ .../workspace/application/grid/row_bloc.dart | 2 +- .../presentation/plugins/doc/document.dart | 1 + .../plugins/grid/src/layout/sizes.dart | 1 + .../src/widgets/content/cell_builder.dart | 44 +++++++--- .../src/widgets/content/checkbox_cell.dart | 47 +++++++++++ .../grid/src/widgets/content/date_cell.dart | 47 +++++++++++ .../grid/src/widgets/content/grid_cell.dart | 80 ------------------- .../grid/src/widgets/content/grid_row.dart | 6 +- .../grid/src/widgets/content/number_cell.dart | 47 +++++++++++ .../src/widgets/content/selection_cell.dart | 75 +++++++++++++++++ .../grid/src/widgets/content/text_cell.dart | 70 ++++++++++++++++ .../grid/src/widgets/header/header.dart | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 15 +++- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- .../flowy-grid/src/services/grid_editor.rs | 14 ++++ 24 files changed, 636 insertions(+), 101 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart delete mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 54275b95b3..5b91d8a545 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -110,6 +110,46 @@ class HomeDepsResolver { ), ); + getIt.registerFactoryParam( + (field, cell) => TextCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => SelectionCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => NumberCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => DateCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => CheckboxCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart new file mode 100644 index 0000000000..c5098155cb --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -0,0 +1 @@ +class CellService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart new file mode 100644 index 0000000000..8f0de7fb32 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -0,0 +1,46 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'cell_service.dart'; + +part 'checkbox_cell_bloc.freezed.dart'; + +class CheckboxCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + CheckboxCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(CheckboxCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class CheckboxCellEvent with _$CheckboxCellEvent { + const factory CheckboxCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class CheckboxCellState with _$CheckboxCellState { + const factory CheckboxCellState({ + required Cell? cell, + }) = _CheckboxCellState; + + factory CheckboxCellState.initial(Cell? cell) => CheckboxCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart new file mode 100644 index 0000000000..c8b5e97f2d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -0,0 +1,46 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'cell_service.dart'; + +part 'date_cell_bloc.freezed.dart'; + +class DateCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + DateCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(DateCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class DateCellEvent with _$DateCellEvent { + const factory DateCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class DateCellState with _$DateCellState { + const factory DateCellState({ + required Cell? cell, + }) = _DateCellState; + + factory DateCellState.initial(Cell? cell) => DateCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart new file mode 100644 index 0000000000..b216550a81 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -0,0 +1,46 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'cell_service.dart'; + +part 'number_cell_bloc.freezed.dart'; + +class NumberCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + NumberCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(NumberCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class NumberCellEvent with _$NumberCellEvent { + const factory NumberCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class NumberCellState with _$NumberCellState { + const factory NumberCellState({ + required Cell? cell, + }) = _NumberCellState; + + factory NumberCellState.initial(Cell? cell) => NumberCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart new file mode 100644 index 0000000000..5e7a6e8e22 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -0,0 +1,46 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'cell_service.dart'; + +part 'selection_cell_bloc.freezed.dart'; + +class SelectionCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + SelectionCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(SelectionCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class SelectionCellEvent with _$SelectionCellEvent { + const factory SelectionCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class SelectionCellState with _$SelectionCellState { + const factory SelectionCellState({ + required Cell? cell, + }) = _SelectionCellState; + + factory SelectionCellState.initial(Cell? cell) => SelectionCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart new file mode 100644 index 0000000000..cce4ff9224 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -0,0 +1,48 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'cell_service.dart'; + +part 'text_cell_bloc.freezed.dart'; + +class TextCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + TextCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(TextCellState.initial(cell?.content ?? "")) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + updateText: (_UpdateText value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class TextCellEvent with _$TextCellEvent { + const factory TextCellEvent.initial() = _InitialCell; + const factory TextCellEvent.updateText(String text) = _UpdateText; +} + +@freezed +abstract class TextCellState with _$TextCellState { + const factory TextCellState({ + required String content, + }) = _TextCellState; + + factory TextCellState.initial(String content) => TextCellState(content: content); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart index 844360fa9b..39badc922a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -1,7 +1,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:dartz/dartz.dart'; import 'dart:async'; import 'column_service.dart'; import 'data.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 3cbe922a58..d28df04c62 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -5,3 +5,9 @@ export 'grid_service.dart'; export 'data.dart'; export 'column_service.dart'; export 'column_bloc.dart'; +export 'cell_bloc/text_cell_bloc.dart'; +export 'cell_bloc/number_cell_bloc.dart'; +export 'cell_bloc/selection_cell_bloc.dart'; +export 'cell_bloc/date_cell_bloc.dart'; +export 'cell_bloc/checkbox_cell_bloc.dart'; +export 'cell_bloc/cell_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 9af22beba9..d2852900d9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -34,7 +34,7 @@ class RowBloc extends Bloc { @freezed abstract class RowEvent with _$RowEvent { - const factory RowEvent.initial(GridRowData data) = _InitialRow; + const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.activeRow() = _ActiveRow; const factory RowEvent.disactiveRow() = _DisactiveRow; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart index 53e0bf58aa..249d47011b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -141,6 +141,7 @@ class _DocumentLeftBarItemState extends State { @override void dispose() { _controller.dispose(); + _focusNode.removeListener(_handleFocusChanged); _focusNode.dispose(); super.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index e669a78217..5f8f94e1a2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -10,6 +10,7 @@ class GridSize { static double get trailHeaderPadding => 140 * scale; static double get headerContentPadding => 8 * scale; static double get cellContentPadding => 8 * scale; + // static EdgeInsets get headerContentInsets => EdgeInsets.symmetric( horizontal: GridSize.headerContentPadding, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index efe5a0bd3e..754678ef8e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,17 +1,35 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'grid_cell.dart'; +import 'package:flutter/widgets.dart'; +import 'checkbox_cell.dart'; +import 'date_cell.dart'; +import 'number_cell.dart'; +import 'selection_cell.dart'; +import 'text_cell.dart'; -class GridCellBuilder { - static GridCellWidget buildCell(Field? field, Cell? cell) { - if (field == null || cell == null) { - return GridTextCell("123123123"); - } - - switch (field.fieldType) { - case FieldType.RichText: - return GridTextCell(cell.content); - default: - return const BlankCell(); - } +Widget buildGridCell(Field field, Cell? cell) { + switch (field.fieldType) { + case FieldType.Checkbox: + return CheckboxCell(field: field, cell: cell); + case FieldType.DateTime: + return DateCell(field: field, cell: cell); + case FieldType.MultiSelect: + return MultiSelectCell(field: field, cell: cell); + case FieldType.Number: + return NumberCell(field: field, cell: cell); + case FieldType.RichText: + return GridTextCell(field: field, cell: cell); + case FieldType.SingleSelect: + return SingleSelectCell(field: field, cell: cell); + default: + return const BlankCell(); + } +} + +class BlankCell extends StatelessWidget { + const BlankCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart new file mode 100644 index 0000000000..d3d2b57735 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -0,0 +1,47 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class CheckboxCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const CheckboxCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _CheckboxCellState(); +} + +class _CheckboxCellState extends State { + late CheckboxCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart new file mode 100644 index 0000000000..e1661fdffa --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -0,0 +1,47 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DateCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const DateCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _DateCellState(); +} + +class _DateCellState extends State { + late DateCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart deleted file mode 100755 index be04555bd4..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:flutter/material.dart'; - -/// The interface of base cell. -abstract class GridCellWidget extends StatelessWidget { - final canSelect = true; - - const GridCellWidget({Key? key}) : super(key: key); -} - -class GridTextCell extends GridCellWidget { - late final TextEditingController _controller; - - GridTextCell(String content, {Key? key}) : super(key: key) { - _controller = TextEditingController(text: content); - } - - @override - Widget build(BuildContext context) { - return TextField( - controller: _controller, - onChanged: (value) {}, - maxLines: 1, - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - decoration: const InputDecoration( - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - isDense: true, - ), - ); - } -} - -class DateCell extends GridCellWidget { - final String content; - const DateCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class NumberCell extends GridCellWidget { - final String content; - const NumberCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class SingleSelectCell extends GridCellWidget { - final String content; - const SingleSelectCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class MultiSelectCell extends GridCellWidget { - final String content; - const MultiSelectCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class BlankCell extends GridCellWidget { - const BlankCell({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container(); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index dce4b61d4f..c23bf8f533 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -22,7 +22,7 @@ class _GridRowWidgetState extends State { @override void initState() { - _rowBloc = getIt(param1: widget.data); + _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); super.initState(); } @@ -54,7 +54,7 @@ class _GridRowWidgetState extends State { @override Future dispose() async { - _rowBloc.close(); + await _rowBloc.close(); super.dispose(); } @@ -69,7 +69,7 @@ class _GridRowWidgetState extends State { final cellData = state.data.cellMap[field.id]; return CellContainer( width: field.width.toDouble(), - child: GridCellBuilder.buildCell(field, cellData), + child: buildGridCell(field, cellData), ); }, ).toList(), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart new file mode 100644 index 0000000000..86b9863019 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -0,0 +1,47 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class NumberCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const NumberCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _NumberCellState(); +} + +class _NumberCellState extends State { + late NumberCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart new file mode 100644 index 0000000000..047cff7475 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -0,0 +1,75 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; + +class SingleSelectCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const SingleSelectCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _SingleSelectCellState(); +} + +class _SingleSelectCellState extends State { + late SelectionCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container(); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} + +//---------------------------------------------------------------- +class MultiSelectCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const MultiSelectCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _MultiSelectCellState(); +} + +class _MultiSelectCellState extends State { + late SelectionCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container(); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart new file mode 100644 index 0000000000..7661ddc22f --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -0,0 +1,70 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +/// The interface of base cell. + +class GridTextCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const GridTextCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _GridTextCellState(); +} + +class _GridTextCellState extends State { + late TextEditingController _controller; + final _focusNode = FocusNode(); + late TextCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _controller = TextEditingController(text: _cellBloc.state.content); + _focusNode.addListener(_focusChanged); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return TextField( + controller: _controller, + focusNode: _focusNode, + onChanged: (value) {}, + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + ); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + _focusNode.removeListener(_focusChanged); + _focusNode.dispose(); + super.dispose(); + } + + void _focusChanged() { + _cellBloc.add(TextCellEvent.updateText(_controller.text)); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index d3cf4a5255..83d24535f4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -43,7 +43,7 @@ class GridHeader extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: fields), + create: (context) => getIt(param1: fields)..add(const ColumnEvent.initial()), child: BlocBuilder( builder: (context, state) { final headers = state.fields diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index eb17b1f35e..087d5c51cd 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,6 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow}; +use flowy_grid_data_model::entities::{ + Cell, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, +}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -47,3 +49,14 @@ pub(crate) async fn create_row_handler( let _ = editor.create_empty_row().await?; Ok(()) } + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn update_cell_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let cell: Cell = data.into_inner(); + let editor = manager.get_grid_editor(id.as_ref())?; + let _ = editor.create_empty_row().await?; + Ok(()) +} diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index f171e27826..773e632191 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -11,7 +11,8 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetRows, get_rows_handler) .event(GridEvent::GetFields, get_fields_handler) - .event(GridEvent::CreateRow, create_row_handler); + .event(GridEvent::CreateRow, create_row_handler) + .event(GridEvent::UpdateCell, update_cell_handler); module } @@ -30,4 +31,7 @@ pub enum GridEvent { #[event(input = "GridId")] CreateRow = 3, + + #[event(input = "Cell")] + UpdateCell = 4, } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 9512e59b26..096735c07d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -15,6 +15,7 @@ use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; +use dashmap::mapref::one::Ref; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; @@ -28,6 +29,7 @@ pub struct ClientGridEditor { kv_persistence: Arc, field_map: DashMap, + cell_map: DashMap, } impl ClientGridEditor { @@ -44,6 +46,7 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; let grid_pad = Arc::new(RwLock::new(grid_pad)); + let cell_map = DashMap::new(); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -52,17 +55,20 @@ impl ClientGridEditor { rev_manager, kv_persistence, field_map, + cell_map, })) } pub async fn create_empty_row(&self) -> FlowyResult<()> { let row = RawRow::new(&uuid(), &self.grid_id, vec![]); + self.cell_map.insert(row.id.clone(), row.clone()); self.create_row(row).await?; Ok(()) } async fn create_row(&self, row: RawRow) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?; + self.cell_map.insert(row.id.clone(), row.clone()); let _ = self.kv_persistence.set(row)?; Ok(()) } @@ -73,6 +79,13 @@ impl ClientGridEditor { Ok(()) } + // pub async fn update_row(&self, cell: Cell) -> FlowyResult<()> { + // match self.cell_map.get(&cell.id) { + // None => Err(FlowyError::internal().context(format!("Can't find cell with id: {}", cell.id))), + // Some(raw_cell) => {} + // } + // } + pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(&field)?)).await?; let _ = self.kv_persistence.set(field)?; @@ -99,6 +112,7 @@ impl ClientGridEditor { tracing::error!("Can't find the field with {}", field_id); return None; } + self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); let field = some_field.unwrap(); match stringify_deserialize(raw_cell.data, field.value()) { From e45be3b81e0b60ea089020322b8b2564b9b164f1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 12:01:31 +0800 Subject: [PATCH 026/179] chore: add grid meta --- .../application/grid/grid_service.dart | 9 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../flowy-grid-data-model/grid.pb.dart | 682 +---- .../flowy-grid-data-model/grid.pbenum.dart | 27 - .../flowy-grid-data-model/grid.pbjson.dart | 138 +- .../flowy-grid-data-model/meta.pb.dart | 584 +++++ .../flowy-grid-data-model/meta.pbenum.dart | 34 + .../flowy-grid-data-model/meta.pbjson.dart | 125 + .../flowy-grid-data-model/meta.pbserver.dart | 9 + .../flowy-grid-data-model/protobuf.dart | 1 + .../protobuf/flowy-grid/event_map.pbenum.dart | 2 + .../protobuf/flowy-grid/event_map.pbjson.dart | 3 +- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 14 +- .../src/protobuf/model/event_map.rs | 7 +- .../src/protobuf/proto/event_map.proto | 1 + .../flowy-grid/src/services/grid_builder.rs | 29 +- .../flowy-grid/src/services/grid_editor.rs | 60 +- .../flowy-grid/src/services/kv_persistence.rs | 36 +- .../src/client_grid/grid_pad.rs | 110 +- .../src/entities/grid.rs | 272 +- .../src/entities/meta.rs | 215 ++ .../flowy-grid-data-model/src/entities/mod.rs | 2 + .../src/protobuf/model/grid.rs | 2329 ++--------------- .../src/protobuf/model/meta.rs | 2040 +++++++++++++++ .../src/protobuf/model/mod.rs | 3 + .../src/protobuf/proto/grid.proto | 58 +- .../src/protobuf/proto/meta.proto | 50 + .../flowy-grid-data-model/tests/serde_test.rs | 50 +- 29 files changed, 3529 insertions(+), 3382 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart create mode 100644 shared-lib/flowy-grid-data-model/src/entities/meta.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 5f7f56fb45..e519b0a90d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -16,18 +16,17 @@ class GridService { return GridEventCreateRow(GridId(value: gridId)).send(); } - Future> getRows({required String gridId, required RepeatedRowOrder rowOrders}) { + Future> getRows({required String gridId, required List rowOrders}) { final payload = QueryRowPayload.create() ..gridId = gridId - ..rowOrders = rowOrders; + ..rowOrders = RepeatedRowOrder(items: rowOrders); return GridEventGetRows(payload).send(); } - Future> getFields( - {required String gridId, required RepeatedFieldOrder fieldOrders}) { + Future> getFields({required String gridId, required List fieldOrders}) { final payload = QueryFieldPayload.create() ..gridId = gridId - ..fieldOrders = fieldOrders; + ..fieldOrders = RepeatedFieldOrder(items: fieldOrders); return GridEventGetFields(payload).send(); } } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index b62b350f5e..4aeda8ede9 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -69,3 +69,20 @@ class GridEventCreateRow { } } +class GridEventUpdateCell { + Cell request; + GridEventUpdateCell(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.UpdateCell.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 6fd298b16d..c853bb867b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -9,33 +9,29 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'grid.pbenum.dart'; - -export 'grid.pbenum.dart'; - class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false ; Grid._() : super(); factory Grid({ $core.String? id, - RepeatedFieldOrder? fieldOrders, - RepeatedRowOrder? rowOrders, + $core.Iterable? fieldOrders, + $core.Iterable? rowOrders, }) { final _result = create(); if (id != null) { _result.id = id; } if (fieldOrders != null) { - _result.fieldOrders = fieldOrders; + _result.fieldOrders.addAll(fieldOrders); } if (rowOrders != null) { - _result.rowOrders = rowOrders; + _result.rowOrders.addAll(rowOrders); } return _result; } @@ -70,47 +66,26 @@ class Grid extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - RepeatedFieldOrder get fieldOrders => $_getN(1); - @$pb.TagNumber(2) - set fieldOrders(RepeatedFieldOrder v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasFieldOrders() => $_has(1); - @$pb.TagNumber(2) - void clearFieldOrders() => clearField(2); - @$pb.TagNumber(2) - RepeatedFieldOrder ensureFieldOrders() => $_ensure(1); + $core.List get fieldOrders => $_getList(1); @$pb.TagNumber(3) - RepeatedRowOrder get rowOrders => $_getN(2); - @$pb.TagNumber(3) - set rowOrders(RepeatedRowOrder v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasRowOrders() => $_has(2); - @$pb.TagNumber(3) - void clearRowOrders() => clearField(3); - @$pb.TagNumber(3) - RepeatedRowOrder ensureRowOrders() => $_ensure(2); + $core.List get rowOrders => $_getList(2); } class FieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..hasRequiredFields = false ; FieldOrder._() : super(); factory FieldOrder({ $core.String? fieldId, - $core.bool? visibility, }) { final _result = create(); if (fieldId != null) { _result.fieldId = fieldId; } - if (visibility != null) { - _result.visibility = visibility; - } return _result; } factory FieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -142,15 +117,6 @@ class FieldOrder extends $pb.GeneratedMessage { $core.bool hasFieldId() => $_has(0); @$pb.TagNumber(1) void clearFieldId() => clearField(1); - - @$pb.TagNumber(2) - $core.bool get visibility => $_getBF(1); - @$pb.TagNumber(2) - set visibility($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasVisibility() => $_has(1); - @$pb.TagNumber(2) - void clearVisibility() => clearField(2); } class RepeatedFieldOrder extends $pb.GeneratedMessage { @@ -194,265 +160,20 @@ class RepeatedFieldOrder extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } -class Field extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') - ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) - ..hasRequiredFields = false - ; - - Field._() : super(); - factory Field({ - $core.String? id, - $core.String? name, - $core.String? desc, - FieldType? fieldType, - $core.bool? frozen, - $core.int? width, - AnyData? typeOptions, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (desc != null) { - _result.desc = desc; - } - if (fieldType != null) { - _result.fieldType = fieldType; - } - if (frozen != null) { - _result.frozen = frozen; - } - if (width != null) { - _result.width = width; - } - if (typeOptions != null) { - _result.typeOptions = typeOptions; - } - return _result; - } - factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Field clone() => Field()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Field create() => Field._(); - Field createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Field? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); - @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); - @$pb.TagNumber(2) - void clearName() => clearField(2); - - @$pb.TagNumber(3) - $core.String get desc => $_getSZ(2); - @$pb.TagNumber(3) - set desc($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasDesc() => $_has(2); - @$pb.TagNumber(3) - void clearDesc() => clearField(3); - - @$pb.TagNumber(4) - FieldType get fieldType => $_getN(3); - @$pb.TagNumber(4) - set fieldType(FieldType v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasFieldType() => $_has(3); - @$pb.TagNumber(4) - void clearFieldType() => clearField(4); - - @$pb.TagNumber(5) - $core.bool get frozen => $_getBF(4); - @$pb.TagNumber(5) - set frozen($core.bool v) { $_setBool(4, v); } - @$pb.TagNumber(5) - $core.bool hasFrozen() => $_has(4); - @$pb.TagNumber(5) - void clearFrozen() => clearField(5); - - @$pb.TagNumber(6) - $core.int get width => $_getIZ(5); - @$pb.TagNumber(6) - set width($core.int v) { $_setSignedInt32(5, v); } - @$pb.TagNumber(6) - $core.bool hasWidth() => $_has(5); - @$pb.TagNumber(6) - void clearWidth() => clearField(6); - - @$pb.TagNumber(7) - AnyData get typeOptions => $_getN(6); - @$pb.TagNumber(7) - set typeOptions(AnyData v) { setField(7, v); } - @$pb.TagNumber(7) - $core.bool hasTypeOptions() => $_has(6); - @$pb.TagNumber(7) - void clearTypeOptions() => clearField(7); - @$pb.TagNumber(7) - AnyData ensureTypeOptions() => $_ensure(6); -} - -class RepeatedField extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) - ..hasRequiredFields = false - ; - - RepeatedField._() : super(); - factory RepeatedField({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedField clone() => RepeatedField()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedField create() => RepeatedField._(); - RepeatedField createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedField? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - -class AnyData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - AnyData._() : super(); - factory AnyData({ - $core.String? typeId, - $core.List<$core.int>? value, - }) { - final _result = create(); - if (typeId != null) { - _result.typeId = typeId; - } - if (value != null) { - _result.value = value; - } - return _result; - } - factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory AnyData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - AnyData clone() => AnyData()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static AnyData create() => AnyData._(); - AnyData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static AnyData? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get typeId => $_getSZ(0); - @$pb.TagNumber(1) - set typeId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasTypeId() => $_has(0); - @$pb.TagNumber(1) - void clearTypeId() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get value => $_getN(1); - @$pb.TagNumber(2) - set value($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasValue() => $_has(1); - @$pb.TagNumber(2) - void clearValue() => clearField(2); -} - class RowOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..hasRequiredFields = false ; RowOrder._() : super(); factory RowOrder({ - $core.String? gridId, $core.String? rowId, - $core.bool? visibility, }) { final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } if (rowId != null) { _result.rowId = rowId; } - if (visibility != null) { - _result.visibility = visibility; - } return _result; } factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -477,31 +198,13 @@ class RowOrder extends $pb.GeneratedMessage { static RowOrder? _defaultInstance; @$pb.TagNumber(1) - $core.String get gridId => $_getSZ(0); + $core.String get rowId => $_getSZ(0); @$pb.TagNumber(1) - set gridId($core.String v) { $_setString(0, v); } + set rowId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasGridId() => $_has(0); + $core.bool hasRowId() => $_has(0); @$pb.TagNumber(1) - void clearGridId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.bool get visibility => $_getBF(2); - @$pb.TagNumber(3) - set visibility($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasVisibility() => $_has(2); - @$pb.TagNumber(3) - void clearVisibility() => clearField(3); + void clearRowId() => clearField(1); } class RepeatedRowOrder extends $pb.GeneratedMessage { @@ -545,235 +248,6 @@ class RepeatedRowOrder extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } -class RawRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RawRow', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..m<$core.String, RawCell>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RawRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: RawCell.create) - ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - RawRow._() : super(); - factory RawRow({ - $core.String? id, - $core.String? gridId, - $core.Map<$core.String, RawCell>? cellByFieldId, - $core.int? height, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (gridId != null) { - _result.gridId = gridId; - } - if (cellByFieldId != null) { - _result.cellByFieldId.addAll(cellByFieldId); - } - if (height != null) { - _result.height = height; - } - return _result; - } - factory RawRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RawRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RawRow clone() => RawRow()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RawRow copyWith(void Function(RawRow) updates) => super.copyWith((message) => updates(message as RawRow)) as RawRow; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RawRow create() => RawRow._(); - RawRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RawRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RawRow? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get gridId => $_getSZ(1); - @$pb.TagNumber(2) - set gridId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasGridId() => $_has(1); - @$pb.TagNumber(2) - void clearGridId() => clearField(2); - - @$pb.TagNumber(3) - $core.Map<$core.String, RawCell> get cellByFieldId => $_getMap(2); - - @$pb.TagNumber(4) - $core.int get height => $_getIZ(3); - @$pb.TagNumber(4) - set height($core.int v) { $_setSignedInt32(3, v); } - @$pb.TagNumber(4) - $core.bool hasHeight() => $_has(3); - @$pb.TagNumber(4) - void clearHeight() => clearField(4); -} - -class RawCell extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RawCell', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) - ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - RawCell._() : super(); - factory RawCell({ - $core.String? id, - $core.String? rowId, - $core.String? fieldId, - AnyData? data, - $core.int? height, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (rowId != null) { - _result.rowId = rowId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (data != null) { - _result.data = data; - } - if (height != null) { - _result.height = height; - } - return _result; - } - factory RawCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RawCell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RawCell clone() => RawCell()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RawCell copyWith(void Function(RawCell) updates) => super.copyWith((message) => updates(message as RawCell)) as RawCell; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RawCell create() => RawCell._(); - RawCell createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RawCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RawCell? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get fieldId => $_getSZ(2); - @$pb.TagNumber(3) - set fieldId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFieldId() => $_has(2); - @$pb.TagNumber(3) - void clearFieldId() => clearField(3); - - @$pb.TagNumber(4) - AnyData get data => $_getN(3); - @$pb.TagNumber(4) - set data(AnyData v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); - @$pb.TagNumber(4) - AnyData ensureData() => $_ensure(3); - - @$pb.TagNumber(5) - $core.int get height => $_getIZ(4); - @$pb.TagNumber(5) - set height($core.int v) { $_setSignedInt32(4, v); } - @$pb.TagNumber(5) - $core.bool hasHeight() => $_has(4); - @$pb.TagNumber(5) - void clearHeight() => clearField(5); -} - -class RepeatedRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) - ..hasRequiredFields = false - ; - - RepeatedRow._() : super(); - factory RepeatedRow({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedRow create() => RepeatedRow._(); - RepeatedRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedRow? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - class Row extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Row', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') @@ -843,6 +317,47 @@ class Row extends $pb.GeneratedMessage { void clearHeight() => clearField(3); } +class RepeatedRow extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) + ..hasRequiredFields = false + ; + + RepeatedRow._() : super(); + factory RepeatedRow({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedRow create() => RepeatedRow._(); + RepeatedRow createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedRow? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class Cell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Cell', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') @@ -918,95 +433,6 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(3); } -class CellChangeset extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellChangeset', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..hasRequiredFields = false - ; - - CellChangeset._() : super(); - factory CellChangeset({ - $core.String? id, - $core.String? rowId, - $core.String? fieldId, - $core.String? data, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (rowId != null) { - _result.rowId = rowId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (data != null) { - _result.data = data; - } - return _result; - } - factory CellChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CellChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CellChangeset clone() => CellChangeset()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CellChangeset copyWith(void Function(CellChangeset) updates) => super.copyWith((message) => updates(message as CellChangeset)) as CellChangeset; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CellChangeset create() => CellChangeset._(); - CellChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CellChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CellChangeset? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get fieldId => $_getSZ(2); - @$pb.TagNumber(3) - set fieldId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFieldId() => $_has(2); - @$pb.TagNumber(3) - void clearFieldId() => clearField(3); - - @$pb.TagNumber(4) - $core.String get data => $_getSZ(3); - @$pb.TagNumber(4) - set data($core.String v) { $_setString(3, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); -} - class CreateGridPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateGridPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart index 661b26532c..0ea2223329 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart @@ -5,30 +5,3 @@ // @dart = 2.12 // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class FieldType extends $pb.ProtobufEnum { - static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); - static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); - static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime'); - static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect'); - static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect'); - static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox'); - - static const $core.List values = [ - RichText, - Number, - DateTime, - SingleSelect, - MultiSelect, - Checkbox, - ]; - - static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values); - static FieldType? valueOf($core.int value) => _byValue[value]; - - const FieldType._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 81257592ac..96bfd55dfd 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -8,44 +8,28 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use fieldTypeDescriptor instead') -const FieldType$json = const { - '1': 'FieldType', - '2': const [ - const {'1': 'RichText', '2': 0}, - const {'1': 'Number', '2': 1}, - const {'1': 'DateTime', '2': 2}, - const {'1': 'SingleSelect', '2': 3}, - const {'1': 'MultiSelect', '2': 4}, - const {'1': 'Checkbox', '2': 5}, - ], -}; - -/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ=='); @$core.Deprecated('Use gridDescriptor instead') const Grid$json = const { '1': 'Grid', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, - const {'1': 'row_orders', '3': 3, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'}, + const {'1': 'row_orders', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBI2CgxmaWVsZF9vcmRlcnMYAiABKAsyEy5SZXBlYXRlZEZpZWxkT3JkZXJSC2ZpZWxkT3JkZXJzEjAKCnJvd19vcmRlcnMYAyABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', '2': const [ const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'visibility', '3': 2, '4': 1, '5': 8, '10': 'visibility'}, ], }; /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEh4KCnZpc2liaWxpdHkYAiABKAhSCnZpc2liaWxpdHk='); +final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); @$core.Deprecated('Use repeatedFieldOrderDescriptor instead') const RepeatedFieldOrder$json = const { '1': 'RepeatedFieldOrder', @@ -56,55 +40,16 @@ const RepeatedFieldOrder$json = const { /// Descriptor for `RepeatedFieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedFieldOrderDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEZpZWxkT3JkZXISIQoFaXRlbXMYASADKAsyCy5GaWVsZE9yZGVyUgVpdGVtcw=='); -@$core.Deprecated('Use fieldDescriptor instead') -const Field$json = const { - '1': 'Field', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, - const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, - const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, - const {'1': 'width', '3': 6, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_options', '3': 7, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, - ], -}; - -/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIUCgV3aWR0aBgGIAEoBVIFd2lkdGgSKwoMdHlwZV9vcHRpb25zGAcgASgLMgguQW55RGF0YVILdHlwZU9wdGlvbnM='); -@$core.Deprecated('Use repeatedFieldDescriptor instead') -const RepeatedField$json = const { - '1': 'RepeatedField', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); -@$core.Deprecated('Use anyDataDescriptor instead') -const AnyData$json = const { - '1': 'AnyData', - '2': const [ - const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'}, - const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, - ], -}; - -/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU='); @$core.Deprecated('Use rowOrderDescriptor instead') const RowOrder$json = const { '1': 'RowOrder', '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '10': 'visibility'}, + const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, ], }; /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIeCgp2aXNpYmlsaXR5GAMgASgIUgp2aXNpYmlsaXR5'); +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lk'); @$core.Deprecated('Use repeatedRowOrderDescriptor instead') const RepeatedRowOrder$json = const { '1': 'RepeatedRowOrder', @@ -115,54 +60,6 @@ const RepeatedRowOrder$json = const { /// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z'); -@$core.Deprecated('Use rawRowDescriptor instead') -const RawRow$json = const { - '1': 'RawRow', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RawRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, - const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, - ], - '3': const [RawRow_CellByFieldIdEntry$json], -}; - -@$core.Deprecated('Use rawRowDescriptor instead') -const RawRow_CellByFieldIdEntry$json = const { - '1': 'CellByFieldIdEntry', - '2': const [ - const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, - const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.RawCell', '10': 'value'}, - ], - '7': const {'7': true}, -}; - -/// Descriptor for `RawRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBIWCgZoZWlnaHQYBCABKAVSBmhlaWdodBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); -@$core.Deprecated('Use rawCellDescriptor instead') -const RawCell$json = const { - '1': 'RawCell', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, - const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, - ], -}; - -/// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRhEhYKBmhlaWdodBgFIAEoBVIGaGVpZ2h0'); -@$core.Deprecated('Use repeatedRowDescriptor instead') -const RepeatedRow$json = const { - '1': 'RepeatedRow', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); @$core.Deprecated('Use rowDescriptor instead') const Row$json = const { '1': 'Row', @@ -186,6 +83,16 @@ const Row_CellByFieldIdEntry$json = const { /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use repeatedRowDescriptor instead') +const RepeatedRow$json = const { + '1': 'RepeatedRow', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', @@ -198,19 +105,6 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAMgASgJUgdjb250ZW50'); -@$core.Deprecated('Use cellChangesetDescriptor instead') -const CellChangeset$json = const { - '1': 'CellChangeset', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 9, '10': 'data'}, - ], -}; - -/// Descriptor for `CellChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellChangesetDescriptor = $convert.base64Decode('Cg1DZWxsQ2hhbmdlc2V0Eg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhIKBGRhdGEYBCABKAlSBGRhdGE='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart new file mode 100644 index 0000000000..11370c1fd2 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -0,0 +1,584 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'meta.pbenum.dart'; + +export 'meta.pbenum.dart'; + +class GridMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + GridMeta._() : super(); + factory GridMeta({ + $core.String? gridId, + $core.Iterable? fields, + $core.Iterable? rows, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fields != null) { + _result.fields.addAll(fields); + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory GridMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridMeta clone() => GridMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridMeta copyWith(void Function(GridMeta) updates) => super.copyWith((message) => updates(message as GridMeta)) as GridMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridMeta create() => GridMeta._(); + GridMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get fields => $_getList(1); + + @$pb.TagNumber(3) + $core.List get rows => $_getList(2); +} + +class GridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + GridBlock._() : super(); + factory GridBlock({ + $core.String? id, + $core.Iterable? rows, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlock clone() => GridBlock()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlock create() => GridBlock._(); + GridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlock? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rows => $_getList(1); +} + +class Field extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..hasRequiredFields = false + ; + + Field._() : super(); + factory Field({ + $core.String? id, + $core.String? name, + $core.String? desc, + FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + AnyData? typeOptions, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + if (typeOptions != null) { + _result.typeOptions = typeOptions; + } + return _result; + } + factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Field clone() => Field()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Field create() => Field._(); + Field createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Field? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get desc => $_getSZ(2); + @$pb.TagNumber(3) + set desc($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDesc() => $_has(2); + @$pb.TagNumber(3) + void clearDesc() => clearField(3); + + @$pb.TagNumber(4) + FieldType get fieldType => $_getN(3); + @$pb.TagNumber(4) + set fieldType(FieldType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasFieldType() => $_has(3); + @$pb.TagNumber(4) + void clearFieldType() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get frozen => $_getBF(4); + @$pb.TagNumber(5) + set frozen($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrozen() => $_has(4); + @$pb.TagNumber(5) + void clearFrozen() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get visibility => $_getBF(5); + @$pb.TagNumber(6) + set visibility($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasVisibility() => $_has(5); + @$pb.TagNumber(6) + void clearVisibility() => clearField(6); + + @$pb.TagNumber(7) + $core.int get width => $_getIZ(6); + @$pb.TagNumber(7) + set width($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasWidth() => $_has(6); + @$pb.TagNumber(7) + void clearWidth() => clearField(7); + + @$pb.TagNumber(8) + AnyData get typeOptions => $_getN(7); + @$pb.TagNumber(8) + set typeOptions(AnyData v) { setField(8, v); } + @$pb.TagNumber(8) + $core.bool hasTypeOptions() => $_has(7); + @$pb.TagNumber(8) + void clearTypeOptions() => clearField(8); + @$pb.TagNumber(8) + AnyData ensureTypeOptions() => $_ensure(7); +} + +class RepeatedField extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + RepeatedField._() : super(); + factory RepeatedField({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedField clone() => RepeatedField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedField create() => RepeatedField._(); + RepeatedField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedField? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + +class AnyData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + AnyData._() : super(); + factory AnyData({ + $core.String? typeId, + $core.List<$core.int>? value, + }) { + final _result = create(); + if (typeId != null) { + _result.typeId = typeId; + } + if (value != null) { + _result.value = value; + } + return _result; + } + factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory AnyData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + AnyData clone() => AnyData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static AnyData create() => AnyData._(); + AnyData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static AnyData? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get typeId => $_getSZ(0); + @$pb.TagNumber(1) + set typeId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasTypeId() => $_has(0); + @$pb.TagNumber(1) + void clearTypeId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get value => $_getN(1); + @$pb.TagNumber(2) + set value($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasValue() => $_has(1); + @$pb.TagNumber(2) + void clearValue() => clearField(2); +} + +class RowMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMeta.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..hasRequiredFields = false + ; + + RowMeta._() : super(); + factory RowMeta({ + $core.String? id, + $core.String? gridId, + $core.Map<$core.String, CellMeta>? cellByFieldId, + $core.int? height, + $core.bool? visibility, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (gridId != null) { + _result.gridId = gridId; + } + if (cellByFieldId != null) { + _result.cellByFieldId.addAll(cellByFieldId); + } + if (height != null) { + _result.height = height; + } + if (visibility != null) { + _result.visibility = visibility; + } + return _result; + } + factory RowMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RowMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RowMeta clone() => RowMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RowMeta copyWith(void Function(RowMeta) updates) => super.copyWith((message) => updates(message as RowMeta)) as RowMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RowMeta create() => RowMeta._(); + RowMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RowMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RowMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get gridId => $_getSZ(1); + @$pb.TagNumber(2) + set gridId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasGridId() => $_has(1); + @$pb.TagNumber(2) + void clearGridId() => clearField(2); + + @$pb.TagNumber(3) + $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(2); + + @$pb.TagNumber(4) + $core.int get height => $_getIZ(3); + @$pb.TagNumber(4) + set height($core.int v) { $_setSignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasHeight() => $_has(3); + @$pb.TagNumber(4) + void clearHeight() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get visibility => $_getBF(4); + @$pb.TagNumber(5) + set visibility($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasVisibility() => $_has(4); + @$pb.TagNumber(5) + void clearVisibility() => clearField(5); +} + +class CellMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) + ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + CellMeta._() : super(); + factory CellMeta({ + $core.String? id, + $core.String? rowId, + $core.String? fieldId, + AnyData? data, + $core.int? height, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (rowId != null) { + _result.rowId = rowId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (data != null) { + _result.data = data; + } + if (height != null) { + _result.height = height; + } + return _result; + } + factory CellMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CellMeta clone() => CellMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellMeta copyWith(void Function(CellMeta) updates) => super.copyWith((message) => updates(message as CellMeta)) as CellMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellMeta create() => CellMeta._(); + CellMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get rowId => $_getSZ(1); + @$pb.TagNumber(2) + set rowId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasRowId() => $_has(1); + @$pb.TagNumber(2) + void clearRowId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get fieldId => $_getSZ(2); + @$pb.TagNumber(3) + set fieldId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasFieldId() => $_has(2); + @$pb.TagNumber(3) + void clearFieldId() => clearField(3); + + @$pb.TagNumber(4) + AnyData get data => $_getN(3); + @$pb.TagNumber(4) + set data(AnyData v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasData() => $_has(3); + @$pb.TagNumber(4) + void clearData() => clearField(4); + @$pb.TagNumber(4) + AnyData ensureData() => $_ensure(3); + + @$pb.TagNumber(5) + $core.int get height => $_getIZ(4); + @$pb.TagNumber(5) + set height($core.int v) { $_setSignedInt32(4, v); } + @$pb.TagNumber(5) + $core.bool hasHeight() => $_has(4); + @$pb.TagNumber(5) + void clearHeight() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart new file mode 100644 index 0000000000..2bb3da475b --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart @@ -0,0 +1,34 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class FieldType extends $pb.ProtobufEnum { + static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); + static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime'); + static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect'); + static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect'); + static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox'); + + static const $core.List values = [ + RichText, + Number, + DateTime, + SingleSelect, + MultiSelect, + Checkbox, + ]; + + static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values); + static FieldType? valueOf($core.int value) => _byValue[value]; + + const FieldType._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart new file mode 100644 index 0000000000..eb41930ba4 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -0,0 +1,125 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use fieldTypeDescriptor instead') +const FieldType$json = const { + '1': 'FieldType', + '2': const [ + const {'1': 'RichText', '2': 0}, + const {'1': 'Number', '2': 1}, + const {'1': 'DateTime', '2': 2}, + const {'1': 'SingleSelect', '2': 3}, + const {'1': 'MultiSelect', '2': 4}, + const {'1': 'Checkbox', '2': 5}, + ], +}; + +/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ=='); +@$core.Deprecated('Use gridMetaDescriptor instead') +const GridMeta$json = const { + '1': 'GridMeta', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, + const {'1': 'rows', '3': 3, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + ], +}; + +/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw=='); +@$core.Deprecated('Use gridBlockDescriptor instead') +const GridBlock$json = const { + '1': 'GridBlock', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + ], +}; + +/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); +@$core.Deprecated('Use fieldDescriptor instead') +const Field$json = const { + '1': 'Field', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, + const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, + const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, + const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, + ], +}; + +/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); +@$core.Deprecated('Use repeatedFieldDescriptor instead') +const RepeatedField$json = const { + '1': 'RepeatedField', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); +@$core.Deprecated('Use anyDataDescriptor instead') +const AnyData$json = const { + '1': 'AnyData', + '2': const [ + const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'}, + const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, + ], +}; + +/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU='); +@$core.Deprecated('Use rowMetaDescriptor instead') +const RowMeta$json = const { + '1': 'RowMeta', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, + const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'}, + ], + '3': const [RowMeta_CellByFieldIdEntry$json], +}; + +@$core.Deprecated('Use rowMetaDescriptor instead') +const RowMeta_CellByFieldIdEntry$json = const { + '1': 'CellByFieldIdEntry', + '2': const [ + const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use cellMetaDescriptor instead') +const CellMeta$json = const { + '1': 'CellMeta', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, + const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, + ], +}; + +/// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIcCgRkYXRhGAQgASgLMgguQW55RGF0YVIEZGF0YRIWCgZoZWlnaHQYBSABKAVSBmhlaWdodA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart new file mode 100644 index 0000000000..fdd12ef0bf --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'meta.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart index 3f0100c8d6..2c253e0494 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart @@ -1,2 +1,3 @@ // Auto-generated, do not edit export './grid.pb.dart'; +export './meta.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 29a15a76b3..ac47fe4a51 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -14,12 +14,14 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetRows = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows'); static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, GetRows, GetFields, CreateRow, + UpdateCell, ]; static final $core.Map<$core.int, GridEvent> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 0791be4e50..145521943a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -16,8 +16,9 @@ const GridEvent$json = const { const {'1': 'GetRows', '2': 1}, const {'1': 'GetFields', '2': 2}, const {'1': 'CreateRow', '2': 3}, + const {'1': 'UpdateCell', '2': 4}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAM='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 087d5c51cd..8c91bf1341 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -56,7 +56,7 @@ pub(crate) async fn update_cell_handler( manager: AppData>, ) -> Result<(), FlowyError> { let cell: Cell = data.into_inner(); - let editor = manager.get_grid_editor(id.as_ref())?; - let _ = editor.create_empty_row().await?; + // let editor = manager.get_grid_editor(id.as_ref())?; + // let _ = editor.create_empty_row().await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 95eea5b9cc..83c12b2b78 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -4,7 +4,7 @@ use dashmap::DashMap; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, RawRow}; +use flowy_grid_data_model::entities::{Field, RowMeta}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; @@ -77,18 +77,6 @@ impl GridManager { } } - pub fn save_rows(&self, rows: Vec) -> FlowyResult<()> { - let kv_persistence = self.get_kv_persistence()?; - let _ = kv_persistence.batch_set(rows)?; - Ok(()) - } - - pub fn save_fields(&self, fields: Vec) -> FlowyResult<()> { - let kv_persistence = self.get_kv_persistence()?; - let _ = kv_persistence.batch_set(fields)?; - Ok(()) - } - async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.editor_map.get(grid_id) { None => { diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 6884312f38..028f37bab5 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -29,6 +29,7 @@ pub enum GridEvent { GetRows = 1, GetFields = 2, CreateRow = 3, + UpdateCell = 4, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -42,6 +43,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 1 => ::std::option::Option::Some(GridEvent::GetRows), 2 => ::std::option::Option::Some(GridEvent::GetFields), 3 => ::std::option::Option::Some(GridEvent::CreateRow), + 4 => ::std::option::Option::Some(GridEvent::UpdateCell), _ => ::std::option::Option::None } } @@ -52,6 +54,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetRows, GridEvent::GetFields, GridEvent::CreateRow, + GridEvent::UpdateCell, ]; values } @@ -80,9 +83,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*G\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ + \n\x0fevent_map.proto*W\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ \x0b\n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\ - \x10\x03b\x06proto3\ + \x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index 0f5de19e98..e06c2e56b3 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -5,4 +5,5 @@ enum GridEvent { GetRows = 1; GetFields = 2; CreateRow = 3; + UpdateCell = 4; } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs index 1bce574abb..bfc2fc1568 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -1,7 +1,7 @@ use crate::manager::GridManager; use flowy_collaboration::client_grid::make_grid_delta; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawCell, RawRow, RowOrder}; +use flowy_grid_data_model::entities::{CellMeta, Field, FieldType, Grid, GridMeta, RowMeta, RowOrder}; use lib_infra::uuid; use std::sync::Arc; @@ -9,7 +9,7 @@ pub struct GridBuilder { grid_manager: Arc, grid_id: String, fields: Vec, - rows: Vec, + rows: Vec, } impl GridBuilder { @@ -29,39 +29,32 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RawRow::new(&uuid(), &self.grid_id, vec![]); + let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); self.rows.push(row); self } - pub fn add_row(mut self, cells: Vec) -> Self { - let row = RawRow::new(&uuid(), &self.grid_id, cells); + pub fn add_row(mut self, cells: Vec) -> Self { + let row = RowMeta::new(&uuid(), &self.grid_id, cells); self.rows.push(row); self } pub fn build(self) -> FlowyResult { - let field_orders = self.fields.iter().map(FieldOrder::from).collect::>(); - - let row_orders = self.rows.iter().map(RowOrder::from).collect::>(); - - let grid = Grid { - id: self.grid_id, - field_orders: field_orders.into(), - row_orders: row_orders.into(), + let grid_meta = GridMeta { + grid_id: self.grid_id, + fields: self.fields, + rows: self.rows, }; // let _ = check_rows(&self.fields, &self.rows)?; - let _ = self.grid_manager.save_rows(self.rows)?; - let _ = self.grid_manager.save_fields(self.fields)?; - - let delta = make_grid_delta(&grid); + let delta = make_grid_delta(&grid_meta); Ok(delta.to_delta_str()) } } #[allow(dead_code)] -fn check_rows(fields: &[Field], rows: &[RawRow]) -> FlowyResult<()> { +fn check_rows(fields: &[Field], rows: &[RowMeta]) -> FlowyResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); for row in rows { let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 096735c07d..9bc7b6da05 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -3,19 +3,17 @@ use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use crate::services::stringify::stringify_deserialize; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridChange, GridPad}; +use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, Field, Grid, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, + Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, }; use flowy_sync::{RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; - -use dashmap::mapref::one::Ref; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; @@ -24,12 +22,12 @@ use tokio::sync::RwLock; pub struct ClientGridEditor { grid_id: String, user: Arc, - grid_pad: Arc>, + grid_meta_pad: Arc>, rev_manager: Arc, kv_persistence: Arc, field_map: DashMap, - cell_map: DashMap, + cell_map: DashMap, } impl ClientGridEditor { @@ -45,13 +43,13 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; - let grid_pad = Arc::new(RwLock::new(grid_pad)); + let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); let cell_map = DashMap::new(); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, - grid_pad, + grid_meta_pad, rev_manager, kv_persistence, field_map, @@ -60,16 +58,15 @@ impl ClientGridEditor { } pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RawRow::new(&uuid(), &self.grid_id, vec![]); - self.cell_map.insert(row.id.clone(), row.clone()); + let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); self.create_row(row).await?; Ok(()) } - async fn create_row(&self, row: RawRow) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?; - self.cell_map.insert(row.id.clone(), row.clone()); - let _ = self.kv_persistence.set(row)?; + async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; + // self.cell_map.insert(row.id.clone(), row.clone()); + // let _ = self.kv_persistence.set(row)?; Ok(()) } @@ -87,8 +84,7 @@ impl ClientGridEditor { // } pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_field(&field)?)).await?; - let _ = self.kv_persistence.set(field)?; + let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; Ok(()) } @@ -104,9 +100,9 @@ impl ClientGridEditor { .into_iter() .map(|row_order| row_order.row_id) .collect::>(); - let raw_rows: Vec = self.kv_persistence.batch_get(ids)?; + let row_metas: Vec = self.kv_persistence.batch_get(ids)?; - let make_cell = |field_id: String, raw_cell: RawCell| { + let make_cell = |field_id: String, raw_cell: CellMeta| { let some_field = self.field_map.get(&field_id); if some_field.is_none() { tracing::error!("Can't find the field with {}", field_id); @@ -128,15 +124,15 @@ impl ClientGridEditor { } }; - let rows = raw_rows + let rows = row_metas .into_par_iter() - .map(|raw_row| { + .map(|row_meta| { let mut row = Row { - id: raw_row.id.clone(), + id: row_meta.id.clone(), cell_by_field_id: Default::default(), - height: raw_row.height, + height: row_meta.height, }; - row.cell_by_field_id = raw_row + row.cell_by_field_id = row_meta .cell_by_field_id .into_par_iter() .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) @@ -163,18 +159,18 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> Grid { - self.grid_pad.read().await.grid_data() + self.grid_meta_pad.read().await.grid_data() } pub async fn delta_str(&self) -> String { - self.grid_pad.read().await.delta_str() + self.grid_meta_pad.read().await.delta_str() } async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { - let mut write_guard = self.grid_pad.write().await; + let mut write_guard = self.grid_meta_pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -206,13 +202,13 @@ impl ClientGridEditor { } async fn load_all_fields( - grid_pad: &GridPad, + grid_pad: &GridMetaPad, kv_persistence: &Arc, ) -> FlowyResult> { let field_ids = grid_pad - .field_orders() + .fields() .iter() - .map(|field_order| field_order.field_id.clone()) + .map(|field| field.id.clone()) .collect::>(); let fields = kv_persistence.batch_get::(field_ids)?; @@ -225,10 +221,10 @@ async fn load_all_fields( struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { - type Output = GridPad; + type Output = GridMetaPad; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridPad::from_revisions(object_id, revisions)?; + let pad = GridMetaPad::from_revisions(object_id, revisions)?; Ok(pad) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs index bc398f9cf3..6577c52ecd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -6,8 +6,6 @@ use flowy_database::{ schema::{kv_table, kv_table::dsl}, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::GridIdentifiable; - use lib_sqlite::ConnectionPool; use std::sync::Arc; @@ -135,33 +133,11 @@ impl<'a> KVTransaction for SqliteTransaction<'a> { } } -impl + GridIdentifiable> std::convert::From for KeyValue { - fn from(value: T) -> Self { - let key = value.id().to_string(); - let bytes: Bytes = value.try_into().unwrap(); - let value = bytes.to_vec(); - KeyValue { key, value } - } -} - -// -// impl std::convert::TryInto for KeyValue { - -// type Error = FlowyError; -// -// fn try_into(self) -> Result { -// let bytes = Bytes::from(self.value); -// RawRow::try_from(bytes) -// .map_err(|e| FlowyError::internal().context(format!("Deserialize into raw row failed: {:?}", e))) -// } -// } -// -// impl std::convert::TryInto for KeyValue { -// type Error = FlowyError; -// -// fn try_into(self) -> Result { -// let bytes = Bytes::from(self.value); -// Field::try_from(bytes) -// .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e))) +// impl + GridIdentifiable> std::convert::From for KeyValue { +// fn from(value: T) -> Self { +// let key = value.id().to_string(); +// let bytes: Bytes = value.try_into().unwrap(); +// let value = bytes.to_vec(); +// KeyValue { key, value } // } // } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 51be4dac63..32b3f968b3 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder}; +use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, GridMeta, RowMeta, RowOrder}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::sync::Arc; @@ -9,70 +9,55 @@ use std::sync::Arc; pub type GridDelta = PlainTextDelta; pub type GridDeltaBuilder = PlainTextDeltaBuilder; -pub struct GridPad { - pub(crate) grid: Arc, +pub struct GridMetaPad { + pub(crate) grid_meta: Arc, pub(crate) delta: GridDelta, } -impl GridPad { +impl GridMetaPad { pub fn from_delta(delta: GridDelta) -> CollaborateResult { let s = delta.to_str()?; - let grid: Grid = serde_json::from_str(&s) + let grid: GridMeta = serde_json::from_str(&s) .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?; Ok(Self { - grid: Arc::new(grid), + grid_meta: Arc::new(grid), delta, }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { - let folder_delta: GridDelta = make_delta_from_revisions::(revisions)?; - Self::from_delta(folder_delta) + let grid_delta: GridDelta = make_delta_from_revisions::(revisions)?; + Self::from_delta(grid_delta) } - pub fn create_row(&mut self, row: &RawRow) -> CollaborateResult> { + pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { self.modify_grid(|grid| { - let row_order = RowOrder { - grid_id: grid.id.clone(), - row_id: row.id.clone(), - visibility: true, - }; - grid.row_orders.push(row_order); + grid.rows.push(row); Ok(Some(())) }) } - pub fn create_field(&mut self, field: &Field) -> CollaborateResult> { + pub fn create_field(&mut self, field: Field) -> CollaborateResult> { self.modify_grid(|grid| { - let field_order = FieldOrder { - field_id: field.id.clone(), - visibility: true, - }; - grid.field_orders.push(field_order); + grid.fields.push(field); Ok(Some(())) }) } pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify_grid(|grid| { - grid.row_orders.retain(|row_order| !row_ids.contains(&row_order.row_id)); + grid.rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { - self.modify_grid(|grid| { - match grid - .field_orders - .iter() - .position(|field_order| field_order.field_id == field_id) - { - None => Ok(None), - Some(index) => { - grid.field_orders.remove(index); - Ok(Some(())) - } + self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + grid.fields.remove(index); + Ok(Some(())) } }) } @@ -82,28 +67,45 @@ impl GridPad { } pub fn grid_data(&self) -> Grid { - let grid_ref: &Grid = &self.grid; - grid_ref.clone() + let field_orders = self + .grid_meta + .fields + .iter() + .map(FieldOrder::from) + .collect::>(); + + let row_orders = self + .grid_meta + .rows + .iter() + .map(RowOrder::from) + .collect::>(); + + Grid { + id: "".to_string(), + field_orders, + row_orders, + } } pub fn delta_str(&self) -> String { self.delta.to_delta_str() } - pub fn field_orders(&self) -> &RepeatedFieldOrder { - &self.grid.field_orders + pub fn fields(&self) -> &[Field] { + &self.grid_meta.fields } pub fn modify_grid(&mut self, f: F) -> CollaborateResult> where - F: FnOnce(&mut Grid) -> CollaborateResult>, + F: FnOnce(&mut GridMeta) -> CollaborateResult>, { - let cloned_grid = self.grid.clone(); - match f(Arc::make_mut(&mut self.grid))? { + let cloned_grid = self.grid_meta.clone(); + match f(Arc::make_mut(&mut self.grid_meta))? { None => Ok(None), Some(_) => { let old = json_from_grid(&cloned_grid)?; - let new = json_from_grid(&self.grid)?; + let new = json_from_grid(&self.grid_meta)?; match cal_diff::(old, new) { None => Ok(None), Some(delta) => { @@ -116,7 +118,7 @@ impl GridPad { } } -fn json_from_grid(grid: &Arc) -> CollaborateResult { +fn json_from_grid(grid: &Arc) -> CollaborateResult { let json = serde_json::to_string(grid) .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; Ok(json) @@ -128,28 +130,28 @@ pub struct GridChange { pub md5: String, } -pub fn make_grid_delta(grid: &Grid) -> GridDelta { - let json = serde_json::to_string(&grid).unwrap(); +pub fn make_grid_delta(grid_meta: &GridMeta) -> GridDelta { + let json = serde_json::to_string(&grid_meta).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_grid_revisions(user_id: &str, grid: &Grid) -> RepeatedRevision { - let delta = make_grid_delta(grid); +pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision { + let delta = make_grid_delta(grid_meta); let bytes = delta.to_bytes(); - let revision = Revision::initial_revision(user_id, &grid.id, bytes); + let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes); revision.into() } -impl std::default::Default for GridPad { +impl std::default::Default for GridMetaPad { fn default() -> Self { - let grid = Grid { - id: uuid(), - field_orders: Default::default(), - row_orders: Default::default(), + let grid = GridMeta { + grid_id: uuid(), + fields: vec![], + rows: vec![], }; let delta = make_grid_delta(&grid); - GridPad { - grid: Arc::new(grid), + GridMetaPad { + grid_meta: Arc::new(grid), delta, } } diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index f8b616c22a..ad85fe636b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,3 +1,4 @@ +use crate::entities::{Field, RowMeta}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -6,239 +7,63 @@ use strum_macros::{Display, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_FIELD_WIDTH: i32 = 150; -pub trait GridIdentifiable { - fn id(&self) -> &str; -} - -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] pub id: String, #[pb(index = 2)] - #[serde(flatten)] - pub field_orders: RepeatedFieldOrder, + pub field_orders: Vec, #[pb(index = 3)] - #[serde(flatten)] - pub row_orders: RepeatedRowOrder, + pub row_orders: Vec, } -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] pub field_id: String, - - #[pb(index = 2)] - pub visibility: bool, } impl std::convert::From<&Field> for FieldOrder { fn from(field: &Field) -> Self { Self { field_id: field.id.clone(), - visibility: true, } } } -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedFieldOrder { #[pb(index = 1)] - #[serde(rename(serialize = "field_orders", deserialize = "field_orders"))] pub items: Vec, } -impl std::convert::From> for RepeatedFieldOrder { - fn from(items: Vec) -> Self { - Self { items } - } -} - impl std::ops::Deref for RepeatedFieldOrder { type Target = Vec; - fn deref(&self) -> &Self::Target { &self.items } } -impl std::ops::DerefMut for RepeatedFieldOrder { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct Field { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub name: String, - - #[pb(index = 3)] - pub desc: String, - - #[pb(index = 4)] - pub field_type: FieldType, - - #[pb(index = 5)] - pub frozen: bool, - - #[pb(index = 6)] - pub width: i32, - - #[pb(index = 7)] - pub type_options: AnyData, -} - -impl Field { - pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { - Self { - id: id.to_owned(), - name: name.to_string(), - desc: desc.to_string(), - field_type, - frozen: false, - width: DEFAULT_FIELD_WIDTH, - type_options: Default::default(), - } - } -} - -impl GridIdentifiable for Field { - fn id(&self) -> &str { - &self.id - } -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedField { - #[pb(index = 1)] - pub items: Vec, -} -impl std::ops::Deref for RepeatedField { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedField { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedField { - fn from(items: Vec) -> Self { - Self { items } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] -pub enum FieldType { - RichText = 0, - Number = 1, - DateTime = 2, - SingleSelect = 3, - MultiSelect = 4, - Checkbox = 5, -} - -impl std::default::Default for FieldType { - fn default() -> Self { - FieldType::RichText - } -} - -impl FieldType { - #[allow(dead_code)] - pub fn type_id(&self) -> String { - let ty = self.clone(); - format!("{}", ty as u8) - } - - pub fn from_type_id(type_id: &str) -> Result { - match type_id { - "0" => Ok(FieldType::RichText), - "1" => Ok(FieldType::Number), - "2" => Ok(FieldType::DateTime), - "3" => Ok(FieldType::SingleSelect), - "4" => Ok(FieldType::MultiSelect), - "5" => Ok(FieldType::Checkbox), - _ => Err(format!("Invalid type_id: {}", type_id)), - } - } -} - -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct AnyData { - #[pb(index = 1)] - pub type_id: String, - - #[pb(index = 2)] - pub value: Vec, -} - -impl AnyData { - pub fn from_str(field_type: &FieldType, s: &str) -> AnyData { - Self::from_bytes(field_type, s.as_bytes().to_vec()) - } - - pub fn from_bytes>(field_type: &FieldType, bytes: T) -> AnyData { - AnyData { - type_id: field_type.type_id(), - value: bytes.as_ref().to_vec(), - } - } -} - -impl ToString for AnyData { - fn to_string(&self) -> String { - match String::from_utf8(self.value.clone()) { - Ok(s) => s, - Err(_) => "".to_owned(), - } - } -} - -#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Default, Clone, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] - pub grid_id: String, - - #[pb(index = 2)] pub row_id: String, - - #[pb(index = 3)] - pub visibility: bool, } -impl std::convert::From<&RawRow> for RowOrder { - fn from(row: &RawRow) -> Self { - Self { - grid_id: row.grid_id.clone(), - row_id: row.id.clone(), - visibility: true, - } +impl std::convert::From<&RowMeta> for RowOrder { + fn from(row: &RowMeta) -> Self { + Self { row_id: row.id.clone() } } } -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedRowOrder { #[pb(index = 1)] - #[serde(rename(serialize = "row_orders", deserialize = "row_orders"))] pub items: Vec, } -impl std::convert::From> for RepeatedRowOrder { - fn from(items: Vec) -> Self { - Self { items } - } -} - impl std::ops::Deref for RepeatedRowOrder { type Target = Vec; fn deref(&self) -> &Self::Target { @@ -253,57 +78,14 @@ impl std::ops::DerefMut for RepeatedRowOrder { } #[derive(Debug, Default, ProtoBuf)] -pub struct RawRow { +pub struct Row { #[pb(index = 1)] pub id: String, #[pb(index = 2)] - pub grid_id: String, + pub cell_by_field_id: HashMap, #[pb(index = 3)] - pub cell_by_field_id: HashMap, - - #[pb(index = 4)] - pub height: i32, -} - -impl RawRow { - pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { - let cell_by_field_id = cells - .into_iter() - .map(|cell| (cell.id.clone(), cell)) - .collect::>(); - - Self { - id: id.to_owned(), - grid_id: grid_id.to_owned(), - cell_by_field_id, - height: DEFAULT_ROW_HEIGHT, - } - } -} - -impl GridIdentifiable for RawRow { - fn id(&self) -> &str { - &self.id - } -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct RawCell { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] - pub field_id: String, - - #[pb(index = 4)] - pub data: AnyData, - - #[pb(index = 5)] pub height: i32, } @@ -331,19 +113,6 @@ impl std::convert::From> for RepeatedRow { Self { items } } } - -#[derive(Debug, Default, ProtoBuf)] -pub struct Row { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub cell_by_field_id: HashMap, - - #[pb(index = 3)] - pub height: i32, -} - #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] @@ -356,21 +125,6 @@ pub struct Cell { pub content: String, } -#[derive(Debug, Default, ProtoBuf)] -pub struct CellChangeset { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] - pub field_id: String, - - #[pb(index = 4)] - pub data: String, -} - #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs new file mode 100644 index 0000000000..22abf8905d --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -0,0 +1,215 @@ +use crate::entities::Row; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use strum_macros::{Display, EnumIter, EnumString}; + +pub const DEFAULT_ROW_HEIGHT: i32 = 36; +pub const DEFAULT_FIELD_WIDTH: i32 = 150; + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct GridMeta { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub fields: Vec, + + #[pb(index = 3)] + pub rows: Vec, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct GridBlock { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub rows: Vec, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct Field { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub desc: String, + + #[pb(index = 4)] + pub field_type: FieldType, + + #[pb(index = 5)] + pub frozen: bool, + + #[pb(index = 6)] + pub visibility: bool, + + #[pb(index = 7)] + pub width: i32, + + #[pb(index = 8)] + pub type_options: AnyData, +} + +impl Field { + pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { + Self { + id: id.to_owned(), + name: name.to_string(), + desc: desc.to_string(), + field_type, + frozen: false, + visibility: true, + width: DEFAULT_FIELD_WIDTH, + type_options: Default::default(), + } + } +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedField { + #[pb(index = 1)] + pub items: Vec, +} +impl std::ops::Deref for RepeatedField { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedField { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +impl std::convert::From> for RepeatedField { + fn from(items: Vec) -> Self { + Self { items } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] +pub enum FieldType { + RichText = 0, + Number = 1, + DateTime = 2, + SingleSelect = 3, + MultiSelect = 4, + Checkbox = 5, +} + +impl std::default::Default for FieldType { + fn default() -> Self { + FieldType::RichText + } +} + +impl FieldType { + #[allow(dead_code)] + pub fn type_id(&self) -> String { + let ty = self.clone(); + format!("{}", ty as u8) + } + + pub fn from_type_id(type_id: &str) -> Result { + match type_id { + "0" => Ok(FieldType::RichText), + "1" => Ok(FieldType::Number), + "2" => Ok(FieldType::DateTime), + "3" => Ok(FieldType::SingleSelect), + "4" => Ok(FieldType::MultiSelect), + "5" => Ok(FieldType::Checkbox), + _ => Err(format!("Invalid type_id: {}", type_id)), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +pub struct AnyData { + #[pb(index = 1)] + pub type_id: String, + + #[pb(index = 2)] + pub value: Vec, +} + +impl AnyData { + pub fn from_str(field_type: &FieldType, s: &str) -> AnyData { + Self::from_bytes(field_type, s.as_bytes().to_vec()) + } + + pub fn from_bytes>(field_type: &FieldType, bytes: T) -> AnyData { + AnyData { + type_id: field_type.type_id(), + value: bytes.as_ref().to_vec(), + } + } +} + +impl ToString for AnyData { + fn to_string(&self) -> String { + match String::from_utf8(self.value.clone()) { + Ok(s) => s, + Err(_) => "".to_owned(), + } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct RowMeta { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub grid_id: String, + + #[pb(index = 3)] + pub cell_by_field_id: HashMap, + + #[pb(index = 4)] + pub height: i32, + + #[pb(index = 5)] + pub visibility: bool, +} + +impl RowMeta { + pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { + let cell_by_field_id = cells + .into_iter() + .map(|cell| (cell.id.clone(), cell)) + .collect::>(); + + Self { + id: id.to_owned(), + grid_id: grid_id.to_owned(), + cell_by_field_id, + height: DEFAULT_ROW_HEIGHT, + visibility: true, + } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct CellMeta { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] + pub field_id: String, + + #[pb(index = 4)] + pub data: AnyData, + + #[pb(index = 5)] + pub height: i32, +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/mod.rs b/shared-lib/flowy-grid-data-model/src/entities/mod.rs index 9ba72a1272..350f8092d5 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/mod.rs @@ -1,3 +1,5 @@ mod grid; +mod meta; pub use grid::*; +pub use meta::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index b1a732e42e..c4f57568e9 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -27,8 +27,8 @@ pub struct Grid { // message fields pub id: ::std::string::String, - pub field_orders: ::protobuf::SingularPtrField, - pub row_orders: ::protobuf::SingularPtrField, + pub field_orders: ::protobuf::RepeatedField, + pub row_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -71,70 +71,54 @@ impl Grid { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // .RepeatedFieldOrder field_orders = 2; + // repeated .FieldOrder field_orders = 2; - pub fn get_field_orders(&self) -> &RepeatedFieldOrder { - self.field_orders.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_field_orders(&self) -> &[FieldOrder] { + &self.field_orders } pub fn clear_field_orders(&mut self) { self.field_orders.clear(); } - pub fn has_field_orders(&self) -> bool { - self.field_orders.is_some() - } - // Param is passed by value, moved - pub fn set_field_orders(&mut self, v: RepeatedFieldOrder) { - self.field_orders = ::protobuf::SingularPtrField::some(v); + pub fn set_field_orders(&mut self, v: ::protobuf::RepeatedField) { + self.field_orders = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_orders(&mut self) -> &mut RepeatedFieldOrder { - if self.field_orders.is_none() { - self.field_orders.set_default(); - } - self.field_orders.as_mut().unwrap() + pub fn mut_field_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.field_orders } // Take field - pub fn take_field_orders(&mut self) -> RepeatedFieldOrder { - self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new()) + pub fn take_field_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.field_orders, ::protobuf::RepeatedField::new()) } - // .RepeatedRowOrder row_orders = 3; + // repeated .RowOrder row_orders = 3; - pub fn get_row_orders(&self) -> &RepeatedRowOrder { - self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_row_orders(&self) -> &[RowOrder] { + &self.row_orders } pub fn clear_row_orders(&mut self) { self.row_orders.clear(); } - pub fn has_row_orders(&self) -> bool { - self.row_orders.is_some() - } - // Param is passed by value, moved - pub fn set_row_orders(&mut self, v: RepeatedRowOrder) { - self.row_orders = ::protobuf::SingularPtrField::some(v); + pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { + self.row_orders = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_orders(&mut self) -> &mut RepeatedRowOrder { - if self.row_orders.is_none() { - self.row_orders.set_default(); - } - self.row_orders.as_mut().unwrap() + pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_orders } // Take field - pub fn take_row_orders(&mut self) -> RepeatedRowOrder { - self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) } } @@ -161,10 +145,10 @@ impl ::protobuf::Message for Grid { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_orders)?; }, 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -181,14 +165,14 @@ impl ::protobuf::Message for Grid { if !self.id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.id); } - if let Some(ref v) = self.field_orders.as_ref() { - let len = v.compute_size(); + for value in &self.field_orders { + let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if let Some(ref v) = self.row_orders.as_ref() { - let len = v.compute_size(); + }; + for value in &self.row_orders { + let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } + }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -198,16 +182,16 @@ impl ::protobuf::Message for Grid { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if let Some(ref v) = self.field_orders.as_ref() { + for v in &self.field_orders { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; - } - if let Some(ref v) = self.row_orders.as_ref() { + }; + for v in &self.row_orders { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; - } + }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -251,12 +235,12 @@ impl ::protobuf::Message for Grid { |m: &Grid| { &m.id }, |m: &mut Grid| { &mut m.id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "field_orders", |m: &Grid| { &m.field_orders }, |m: &mut Grid| { &mut m.field_orders }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "row_orders", |m: &Grid| { &m.row_orders }, |m: &mut Grid| { &mut m.row_orders }, @@ -300,7 +284,6 @@ impl ::protobuf::reflect::ProtobufValue for Grid { pub struct FieldOrder { // message fields pub field_id: ::std::string::String, - pub visibility: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -342,21 +325,6 @@ impl FieldOrder { pub fn take_field_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - - // bool visibility = 2; - - - pub fn get_visibility(&self) -> bool { - self.visibility - } - pub fn clear_visibility(&mut self) { - self.visibility = false; - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.visibility = v; - } } impl ::protobuf::Message for FieldOrder { @@ -371,13 +339,6 @@ impl ::protobuf::Message for FieldOrder { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.visibility = tmp; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -393,9 +354,6 @@ impl ::protobuf::Message for FieldOrder { if !self.field_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.field_id); } - if self.visibility != false { - my_size += 2; - } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -405,9 +363,6 @@ impl ::protobuf::Message for FieldOrder { if !self.field_id.is_empty() { os.write_string(1, &self.field_id)?; } - if self.visibility != false { - os.write_bool(2, self.visibility)?; - } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -451,11 +406,6 @@ impl ::protobuf::Message for FieldOrder { |m: &FieldOrder| { &m.field_id }, |m: &mut FieldOrder| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "visibility", - |m: &FieldOrder| { &m.visibility }, - |m: &mut FieldOrder| { &mut m.visibility }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldOrder", fields, @@ -473,7 +423,6 @@ impl ::protobuf::Message for FieldOrder { impl ::protobuf::Clear for FieldOrder { fn clear(&mut self) { self.field_id.clear(); - self.visibility = false; self.unknown_fields.clear(); } } @@ -656,780 +605,10 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedFieldOrder { } } -#[derive(PartialEq,Clone,Default)] -pub struct Field { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub desc: ::std::string::String, - pub field_type: FieldType, - pub frozen: bool, - pub width: i32, - pub type_options: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Field { - fn default() -> &'a Field { - ::default_instance() - } -} - -impl Field { - pub fn new() -> Field { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string name = 2; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // string desc = 3; - - - pub fn get_desc(&self) -> &str { - &self.desc - } - pub fn clear_desc(&mut self) { - self.desc.clear(); - } - - // Param is passed by value, moved - pub fn set_desc(&mut self, v: ::std::string::String) { - self.desc = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_desc(&mut self) -> &mut ::std::string::String { - &mut self.desc - } - - // Take field - pub fn take_desc(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.desc, ::std::string::String::new()) - } - - // .FieldType field_type = 4; - - - pub fn get_field_type(&self) -> FieldType { - self.field_type - } - pub fn clear_field_type(&mut self) { - self.field_type = FieldType::RichText; - } - - // Param is passed by value, moved - pub fn set_field_type(&mut self, v: FieldType) { - self.field_type = v; - } - - // bool frozen = 5; - - - pub fn get_frozen(&self) -> bool { - self.frozen - } - pub fn clear_frozen(&mut self) { - self.frozen = false; - } - - // Param is passed by value, moved - pub fn set_frozen(&mut self, v: bool) { - self.frozen = v; - } - - // int32 width = 6; - - - pub fn get_width(&self) -> i32 { - self.width - } - pub fn clear_width(&mut self) { - self.width = 0; - } - - // Param is passed by value, moved - pub fn set_width(&mut self, v: i32) { - self.width = v; - } - - // .AnyData type_options = 7; - - - pub fn get_type_options(&self) -> &AnyData { - self.type_options.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_type_options(&mut self) { - self.type_options.clear(); - } - - pub fn has_type_options(&self) -> bool { - self.type_options.is_some() - } - - // Param is passed by value, moved - pub fn set_type_options(&mut self, v: AnyData) { - self.type_options = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_type_options(&mut self) -> &mut AnyData { - if self.type_options.is_none() { - self.type_options.set_default(); - } - self.type_options.as_mut().unwrap() - } - - // Take field - pub fn take_type_options(&mut self) -> AnyData { - self.type_options.take().unwrap_or_else(|| AnyData::new()) - } -} - -impl ::protobuf::Message for Field { - fn is_initialized(&self) -> bool { - for v in &self.type_options { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; - }, - 4 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.frozen = tmp; - }, - 6 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.width = tmp; - }, - 7 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.name); - } - if !self.desc.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.desc); - } - if self.field_type != FieldType::RichText { - my_size += ::protobuf::rt::enum_size(4, self.field_type); - } - if self.frozen != false { - my_size += 2; - } - if self.width != 0 { - my_size += ::protobuf::rt::value_size(6, self.width, ::protobuf::wire_format::WireTypeVarint); - } - if let Some(ref v) = self.type_options.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.name.is_empty() { - os.write_string(2, &self.name)?; - } - if !self.desc.is_empty() { - os.write_string(3, &self.desc)?; - } - if self.field_type != FieldType::RichText { - os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; - } - if self.frozen != false { - os.write_bool(5, self.frozen)?; - } - if self.width != 0 { - os.write_int32(6, self.width)?; - } - if let Some(ref v) = self.type_options.as_ref() { - os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Field { - Field::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &Field| { &m.id }, - |m: &mut Field| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &Field| { &m.name }, - |m: &mut Field| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "desc", - |m: &Field| { &m.desc }, - |m: &mut Field| { &mut m.desc }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "field_type", - |m: &Field| { &m.field_type }, - |m: &mut Field| { &mut m.field_type }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "frozen", - |m: &Field| { &m.frozen }, - |m: &mut Field| { &mut m.frozen }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "width", - |m: &Field| { &m.width }, - |m: &mut Field| { &mut m.width }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "type_options", - |m: &Field| { &m.type_options }, - |m: &mut Field| { &mut m.type_options }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Field", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Field { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Field::new) - } -} - -impl ::protobuf::Clear for Field { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.desc.clear(); - self.field_type = FieldType::RichText; - self.frozen = false; - self.width = 0; - self.type_options.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Field { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Field { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedField { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedField { - fn default() -> &'a RepeatedField { - ::default_instance() - } -} - -impl RepeatedField { - pub fn new() -> RepeatedField { - ::std::default::Default::default() - } - - // repeated .Field items = 1; - - - pub fn get_items(&self) -> &[Field] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedField { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedField { - RepeatedField::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedField| { &m.items }, - |m: &mut RepeatedField| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedField", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedField { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedField::new) - } -} - -impl ::protobuf::Clear for RepeatedField { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedField { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedField { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct AnyData { - // message fields - pub type_id: ::std::string::String, - pub value: ::std::vec::Vec, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a AnyData { - fn default() -> &'a AnyData { - ::default_instance() - } -} - -impl AnyData { - pub fn new() -> AnyData { - ::std::default::Default::default() - } - - // string type_id = 1; - - - pub fn get_type_id(&self) -> &str { - &self.type_id - } - pub fn clear_type_id(&mut self) { - self.type_id.clear(); - } - - // Param is passed by value, moved - pub fn set_type_id(&mut self, v: ::std::string::String) { - self.type_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_type_id(&mut self) -> &mut ::std::string::String { - &mut self.type_id - } - - // Take field - pub fn take_type_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_id, ::std::string::String::new()) - } - - // bytes value = 2; - - - pub fn get_value(&self) -> &[u8] { - &self.value - } - pub fn clear_value(&mut self) { - self.value.clear(); - } - - // Param is passed by value, moved - pub fn set_value(&mut self, v: ::std::vec::Vec) { - self.value = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_value(&mut self) -> &mut ::std::vec::Vec { - &mut self.value - } - - // Take field - pub fn take_value(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.value, ::std::vec::Vec::new()) - } -} - -impl ::protobuf::Message for AnyData { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.value)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.type_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.type_id); - } - if !self.value.is_empty() { - my_size += ::protobuf::rt::bytes_size(2, &self.value); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.type_id.is_empty() { - os.write_string(1, &self.type_id)?; - } - if !self.value.is_empty() { - os.write_bytes(2, &self.value)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> AnyData { - AnyData::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_id", - |m: &AnyData| { &m.type_id }, - |m: &mut AnyData| { &mut m.type_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "value", - |m: &AnyData| { &m.value }, - |m: &mut AnyData| { &mut m.value }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "AnyData", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static AnyData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(AnyData::new) - } -} - -impl ::protobuf::Clear for AnyData { - fn clear(&mut self) { - self.type_id.clear(); - self.value.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for AnyData { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for AnyData { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct RowOrder { // message fields - pub grid_id: ::std::string::String, pub row_id: ::std::string::String, - pub visibility: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1446,33 +625,7 @@ impl RowOrder { ::std::default::Default::default() } - // string grid_id = 1; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // string row_id = 2; + // string row_id = 1; pub fn get_row_id(&self) -> &str { @@ -1497,21 +650,6 @@ impl RowOrder { pub fn take_row_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } - - // bool visibility = 3; - - - pub fn get_visibility(&self) -> bool { - self.visibility - } - pub fn clear_visibility(&mut self) { - self.visibility = false; - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.visibility = v; - } } impl ::protobuf::Message for RowOrder { @@ -1524,18 +662,8 @@ impl ::protobuf::Message for RowOrder { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.visibility = tmp; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1548,14 +676,8 @@ impl ::protobuf::Message for RowOrder { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } - if self.visibility != false { - my_size += 2; + my_size += ::protobuf::rt::string_size(1, &self.row_id); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1563,14 +685,8 @@ impl ::protobuf::Message for RowOrder { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } - if self.visibility != false { - os.write_bool(3, self.visibility)?; + os.write_string(1, &self.row_id)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1610,21 +726,11 @@ impl ::protobuf::Message for RowOrder { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &RowOrder| { &m.grid_id }, - |m: &mut RowOrder| { &mut m.grid_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", |m: &RowOrder| { &m.row_id }, |m: &mut RowOrder| { &mut m.row_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "visibility", - |m: &RowOrder| { &m.visibility }, - |m: &mut RowOrder| { &mut m.visibility }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RowOrder", fields, @@ -1641,9 +747,7 @@ impl ::protobuf::Message for RowOrder { impl ::protobuf::Clear for RowOrder { fn clear(&mut self) { - self.grid_id.clear(); self.row_id.clear(); - self.visibility = false; self.unknown_fields.clear(); } } @@ -1826,780 +930,6 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRowOrder { } } -#[derive(PartialEq,Clone,Default)] -pub struct RawRow { - // message fields - pub id: ::std::string::String, - pub grid_id: ::std::string::String, - pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, RawCell>, - pub height: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RawRow { - fn default() -> &'a RawRow { - ::default_instance() - } -} - -impl RawRow { - pub fn new() -> RawRow { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string grid_id = 2; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // repeated .RawRow.CellByFieldIdEntry cell_by_field_id = 3; - - - pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, RawCell> { - &self.cell_by_field_id - } - pub fn clear_cell_by_field_id(&mut self) { - self.cell_by_field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, RawCell>) { - self.cell_by_field_id = v; - } - - // Mutable pointer to the field. - pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, RawCell> { - &mut self.cell_by_field_id - } - - // Take field - pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, RawCell> { - ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) - } - - // int32 height = 4; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; - } -} - -impl ::protobuf::Message for RawRow { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 3 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_id); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); - if self.height != 0 { - my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_id)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; - if self.height != 0 { - os.write_int32(4, self.height)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RawRow { - RawRow::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &RawRow| { &m.id }, - |m: &mut RawRow| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &RawRow| { &m.grid_id }, - |m: &mut RawRow| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "cell_by_field_id", - |m: &RawRow| { &m.cell_by_field_id }, - |m: &mut RawRow| { &mut m.cell_by_field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &RawRow| { &m.height }, - |m: &mut RawRow| { &mut m.height }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RawRow", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RawRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RawRow::new) - } -} - -impl ::protobuf::Clear for RawRow { - fn clear(&mut self) { - self.id.clear(); - self.grid_id.clear(); - self.cell_by_field_id.clear(); - self.height = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RawRow { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RawRow { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RawCell { - // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - pub data: ::protobuf::SingularPtrField, - pub height: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RawCell { - fn default() -> &'a RawCell { - ::default_instance() - } -} - -impl RawCell { - pub fn new() -> RawCell { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string row_id = 2; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string field_id = 3; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // .AnyData data = 4; - - - pub fn get_data(&self) -> &AnyData { - self.data.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_data(&mut self) { - self.data.clear(); - } - - pub fn has_data(&self) -> bool { - self.data.is_some() - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: AnyData) { - self.data = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut AnyData { - if self.data.is_none() { - self.data.set_default(); - } - self.data.as_mut().unwrap() - } - - // Take field - pub fn take_data(&mut self) -> AnyData { - self.data.take().unwrap_or_else(|| AnyData::new()) - } - - // int32 height = 5; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; - } -} - -impl ::protobuf::Message for RawCell { - fn is_initialized(&self) -> bool { - for v in &self.data { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 4 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } - if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); - } - if let Some(ref v) = self.data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if self.height != 0 { - my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } - if !self.field_id.is_empty() { - os.write_string(3, &self.field_id)?; - } - if let Some(ref v) = self.data.as_ref() { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if self.height != 0 { - os.write_int32(5, self.height)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RawCell { - RawCell::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &RawCell| { &m.id }, - |m: &mut RawCell| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &RawCell| { &m.row_id }, - |m: &mut RawCell| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &RawCell| { &m.field_id }, - |m: &mut RawCell| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "data", - |m: &RawCell| { &m.data }, - |m: &mut RawCell| { &mut m.data }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &RawCell| { &m.height }, - |m: &mut RawCell| { &mut m.height }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RawCell", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RawCell { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RawCell::new) - } -} - -impl ::protobuf::Clear for RawCell { - fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.data.clear(); - self.height = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RawCell { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RawCell { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedRow { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedRow { - fn default() -> &'a RepeatedRow { - ::default_instance() - } -} - -impl RepeatedRow { - pub fn new() -> RepeatedRow { - ::std::default::Default::default() - } - - // repeated .Row items = 1; - - - pub fn get_items(&self) -> &[Row] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedRow { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedRow { - RepeatedRow::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedRow| { &m.items }, - |m: &mut RepeatedRow| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedRow", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedRow::new) - } -} - -impl ::protobuf::Clear for RepeatedRow { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedRow { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedRow { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct Row { // message fields @@ -2831,6 +1161,172 @@ impl ::protobuf::reflect::ProtobufValue for Row { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedRow { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedRow { + fn default() -> &'a RepeatedRow { + ::default_instance() + } +} + +impl RepeatedRow { + pub fn new() -> RepeatedRow { + ::std::default::Default::default() + } + + // repeated .Row items = 1; + + + pub fn get_items(&self) -> &[Row] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedRow { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedRow { + RepeatedRow::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedRow| { &m.items }, + |m: &mut RepeatedRow| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedRow", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedRow { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedRow::new) + } +} + +impl ::protobuf::Clear for RepeatedRow { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedRow { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedRow { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct Cell { // message fields @@ -3074,291 +1570,6 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } -#[derive(PartialEq,Clone,Default)] -pub struct CellChangeset { - // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - pub data: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CellChangeset { - fn default() -> &'a CellChangeset { - ::default_instance() - } -} - -impl CellChangeset { - pub fn new() -> CellChangeset { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string row_id = 2; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string field_id = 3; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string data = 4; - - - pub fn get_data(&self) -> &str { - &self.data - } - pub fn clear_data(&mut self) { - self.data.clear(); - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - self.data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { - &mut self.data - } - - // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for CellChangeset { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } - if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); - } - if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.data); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } - if !self.field_id.is_empty() { - os.write_string(3, &self.field_id)?; - } - if !self.data.is_empty() { - os.write_string(4, &self.data)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CellChangeset { - CellChangeset::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &CellChangeset| { &m.id }, - |m: &mut CellChangeset| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellChangeset| { &m.row_id }, - |m: &mut CellChangeset| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &CellChangeset| { &m.field_id }, - |m: &mut CellChangeset| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "data", - |m: &CellChangeset| { &m.data }, - |m: &mut CellChangeset| { &mut m.data }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CellChangeset", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CellChangeset { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CellChangeset::new) - } -} - -impl ::protobuf::Clear for CellChangeset { - fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.data.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CellChangeset { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CellChangeset { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct CreateGridPayload { // message fields @@ -4109,118 +2320,30 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { } } -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum FieldType { - RichText = 0, - Number = 1, - DateTime = 2, - SingleSelect = 3, - MultiSelect = 4, - Checkbox = 5, -} - -impl ::protobuf::ProtobufEnum for FieldType { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(FieldType::RichText), - 1 => ::std::option::Option::Some(FieldType::Number), - 2 => ::std::option::Option::Some(FieldType::DateTime), - 3 => ::std::option::Option::Some(FieldType::SingleSelect), - 4 => ::std::option::Option::Some(FieldType::MultiSelect), - 5 => ::std::option::Option::Some(FieldType::Checkbox), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [FieldType] = &[ - FieldType::RichText, - FieldType::Number, - FieldType::DateTime, - FieldType::SingleSelect, - FieldType::MultiSelect, - FieldType::Checkbox, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("FieldType", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for FieldType { -} - -impl ::std::default::Default for FieldType { - fn default() -> Self { - FieldType::RichText - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldType { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\"\x80\x01\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrd\ - erR\x0bfieldOrders\x120\n\nrow_orders\x18\x03\x20\x01(\x0b2\x11.Repeated\ - RowOrderR\trowOrders\"G\n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x1e\n\nvisibility\x18\x02\x20\x01(\x08R\nvisibil\ - ity\"7\n\x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b\ - .FieldOrderR\x05items\"\xc5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\ - \x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\ - \x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\ - \x06frozen\x12\x14\n\x05width\x18\x06\x20\x01(\x05R\x05width\x12+\n\x0ct\ - ype_options\x18\x07\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepe\ - atedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"\ - 8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\ - \x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"Z\n\x08RowOrder\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ - \x20\x01(\tR\x05rowId\x12\x1e\n\nvisibility\x18\x03\x20\x01(\x08R\nvisib\ - ility\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\ - \t.RowOrderR\x05items\"\xda\x01\n\x06RawRow\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12C\n\ - \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1a.RawRow.CellByFieldIdEntry\ - R\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\x1a\ - J\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\ - \x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCellR\x05value:\x028\ - \x01\"\x81\x01\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ - \x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\ - \x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06heigh\ - t\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\ - \x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdE\ - ntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\ - \x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03ke\ - y\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\ - \"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08fie\ - ld_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\ - \x01(\tR\x07content\"e\n\rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ - field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\ - \x01(\tR\x04data\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\ - \x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\t\ - R\x05value\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.Repe\ - atedFieldOrderR\x0bfieldOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07gri\ - d_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\ - \x0b2\x11.RepeatedRowOrderR\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichT\ - ext\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\ - \x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\ - \n\x08Checkbox\x10\x05b\x06proto3\ + \n\ngrid.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrderR\x0bfieldOr\ + ders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\trowOrders\"'\ + \n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"7\n\ + \x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOr\ + derR\x05items\"!\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\ + \x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ + Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ + lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ + \x03(\x0b2\x04.RowR\x05items\"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\ + \x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\ + \x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ + ad\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\ + \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orde\ + rs\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ + \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ + rsb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs new file mode 100644 index 0000000000..deaa2a75c2 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -0,0 +1,2040 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `meta.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct GridMeta { + // message fields + pub grid_id: ::std::string::String, + pub fields: ::protobuf::RepeatedField, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridMeta { + fn default() -> &'a GridMeta { + ::default_instance() + } +} + +impl GridMeta { + pub fn new() -> GridMeta { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // repeated .Field fields = 2; + + + pub fn get_fields(&self) -> &[Field] { + &self.fields + } + pub fn clear_fields(&mut self) { + self.fields.clear(); + } + + // Param is passed by value, moved + pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { + self.fields = v; + } + + // Mutable pointer to the field. + pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.fields + } + + // Take field + pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) + } + + // repeated .RowMeta rows = 3; + + + pub fn get_rows(&self) -> &[RowMeta] { + &self.rows + } + pub fn clear_rows(&mut self) { + self.rows.clear(); + } + + // Param is passed by value, moved + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; + } + + // Mutable pointer to the field. + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows + } + + // Take field + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridMeta { + fn is_initialized(&self) -> bool { + for v in &self.fields { + if !v.is_initialized() { + return false; + } + }; + for v in &self.rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; + }, + 3 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + for value in &self.fields { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + for v in &self.fields { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.rows { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridMeta { + GridMeta::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &GridMeta| { &m.grid_id }, + |m: &mut GridMeta| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "fields", + |m: &GridMeta| { &m.fields }, + |m: &mut GridMeta| { &mut m.fields }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "rows", + |m: &GridMeta| { &m.rows }, + |m: &mut GridMeta| { &mut m.rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridMeta", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridMeta::new) + } +} + +impl ::protobuf::Clear for GridMeta { + fn clear(&mut self) { + self.grid_id.clear(); + self.fields.clear(); + self.rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridMeta { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct GridBlock { + // message fields + pub id: ::std::string::String, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlock { + fn default() -> &'a GridBlock { + ::default_instance() + } +} + +impl GridBlock { + pub fn new() -> GridBlock { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // repeated .RowMeta rows = 2; + + + pub fn get_rows(&self) -> &[RowMeta] { + &self.rows + } + pub fn clear_rows(&mut self) { + self.rows.clear(); + } + + // Param is passed by value, moved + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; + } + + // Mutable pointer to the field. + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows + } + + // Take field + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlock { + fn is_initialized(&self) -> bool { + for v in &self.rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + for value in &self.rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + for v in &self.rows { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlock { + GridBlock::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &GridBlock| { &m.id }, + |m: &mut GridBlock| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "rows", + |m: &GridBlock| { &m.rows }, + |m: &mut GridBlock| { &mut m.rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlock", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlock::new) + } +} + +impl ::protobuf::Clear for GridBlock { + fn clear(&mut self) { + self.id.clear(); + self.rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlock { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlock { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Field { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + pub field_type: FieldType, + pub frozen: bool, + pub visibility: bool, + pub width: i32, + pub type_options: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Field { + fn default() -> &'a Field { + ::default_instance() + } +} + +impl Field { + pub fn new() -> Field { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string desc = 3; + + + pub fn get_desc(&self) -> &str { + &self.desc + } + pub fn clear_desc(&mut self) { + self.desc.clear(); + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.desc = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + &mut self.desc + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.desc, ::std::string::String::new()) + } + + // .FieldType field_type = 4; + + + pub fn get_field_type(&self) -> FieldType { + self.field_type + } + pub fn clear_field_type(&mut self) { + self.field_type = FieldType::RichText; + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: FieldType) { + self.field_type = v; + } + + // bool frozen = 5; + + + pub fn get_frozen(&self) -> bool { + self.frozen + } + pub fn clear_frozen(&mut self) { + self.frozen = false; + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.frozen = v; + } + + // bool visibility = 6; + + + pub fn get_visibility(&self) -> bool { + self.visibility + } + pub fn clear_visibility(&mut self) { + self.visibility = false; + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.visibility = v; + } + + // int32 width = 7; + + + pub fn get_width(&self) -> i32 { + self.width + } + pub fn clear_width(&mut self) { + self.width = 0; + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.width = v; + } + + // .AnyData type_options = 8; + + + pub fn get_type_options(&self) -> &AnyData { + self.type_options.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_type_options(&mut self) { + self.type_options.clear(); + } + + pub fn has_type_options(&self) -> bool { + self.type_options.is_some() + } + + // Param is passed by value, moved + pub fn set_type_options(&mut self, v: AnyData) { + self.type_options = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_options(&mut self) -> &mut AnyData { + if self.type_options.is_none() { + self.type_options.set_default(); + } + self.type_options.as_mut().unwrap() + } + + // Take field + pub fn take_type_options(&mut self) -> AnyData { + self.type_options.take().unwrap_or_else(|| AnyData::new()) + } +} + +impl ::protobuf::Message for Field { + fn is_initialized(&self) -> bool { + for v in &self.type_options { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; + }, + 4 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.frozen = tmp; + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.visibility = tmp; + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.width = tmp; + }, + 8 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.name); + } + if !self.desc.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.desc); + } + if self.field_type != FieldType::RichText { + my_size += ::protobuf::rt::enum_size(4, self.field_type); + } + if self.frozen != false { + my_size += 2; + } + if self.visibility != false { + my_size += 2; + } + if self.width != 0 { + my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); + } + if let Some(ref v) = self.type_options.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.name.is_empty() { + os.write_string(2, &self.name)?; + } + if !self.desc.is_empty() { + os.write_string(3, &self.desc)?; + } + if self.field_type != FieldType::RichText { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + if self.frozen != false { + os.write_bool(5, self.frozen)?; + } + if self.visibility != false { + os.write_bool(6, self.visibility)?; + } + if self.width != 0 { + os.write_int32(7, self.width)?; + } + if let Some(ref v) = self.type_options.as_ref() { + os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Field { + Field::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &Field| { &m.id }, + |m: &mut Field| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Field| { &m.name }, + |m: &mut Field| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "desc", + |m: &Field| { &m.desc }, + |m: &mut Field| { &mut m.desc }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "field_type", + |m: &Field| { &m.field_type }, + |m: &mut Field| { &mut m.field_type }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "frozen", + |m: &Field| { &m.frozen }, + |m: &mut Field| { &mut m.frozen }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "visibility", + |m: &Field| { &m.visibility }, + |m: &mut Field| { &mut m.visibility }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "width", + |m: &Field| { &m.width }, + |m: &mut Field| { &mut m.width }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "type_options", + |m: &Field| { &m.type_options }, + |m: &mut Field| { &mut m.type_options }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Field", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Field { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Field::new) + } +} + +impl ::protobuf::Clear for Field { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.desc.clear(); + self.field_type = FieldType::RichText; + self.frozen = false; + self.visibility = false; + self.width = 0; + self.type_options.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Field { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Field { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedField { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedField { + fn default() -> &'a RepeatedField { + ::default_instance() + } +} + +impl RepeatedField { + pub fn new() -> RepeatedField { + ::std::default::Default::default() + } + + // repeated .Field items = 1; + + + pub fn get_items(&self) -> &[Field] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedField { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedField { + RepeatedField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedField| { &m.items }, + |m: &mut RepeatedField| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedField::new) + } +} + +impl ::protobuf::Clear for RepeatedField { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct AnyData { + // message fields + pub type_id: ::std::string::String, + pub value: ::std::vec::Vec, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a AnyData { + fn default() -> &'a AnyData { + ::default_instance() + } +} + +impl AnyData { + pub fn new() -> AnyData { + ::std::default::Default::default() + } + + // string type_id = 1; + + + pub fn get_type_id(&self) -> &str { + &self.type_id + } + pub fn clear_type_id(&mut self) { + self.type_id.clear(); + } + + // Param is passed by value, moved + pub fn set_type_id(&mut self, v: ::std::string::String) { + self.type_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_id(&mut self) -> &mut ::std::string::String { + &mut self.type_id + } + + // Take field + pub fn take_type_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_id, ::std::string::String::new()) + } + + // bytes value = 2; + + + pub fn get_value(&self) -> &[u8] { + &self.value + } + pub fn clear_value(&mut self) { + self.value.clear(); + } + + // Param is passed by value, moved + pub fn set_value(&mut self, v: ::std::vec::Vec) { + self.value = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_value(&mut self) -> &mut ::std::vec::Vec { + &mut self.value + } + + // Take field + pub fn take_value(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.value, ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for AnyData { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.value)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.type_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.type_id); + } + if !self.value.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.value); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.type_id.is_empty() { + os.write_string(1, &self.type_id)?; + } + if !self.value.is_empty() { + os.write_bytes(2, &self.value)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> AnyData { + AnyData::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "type_id", + |m: &AnyData| { &m.type_id }, + |m: &mut AnyData| { &mut m.type_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "value", + |m: &AnyData| { &m.value }, + |m: &mut AnyData| { &mut m.value }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "AnyData", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static AnyData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(AnyData::new) + } +} + +impl ::protobuf::Clear for AnyData { + fn clear(&mut self) { + self.type_id.clear(); + self.value.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for AnyData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for AnyData { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RowMeta { + // message fields + pub id: ::std::string::String, + pub grid_id: ::std::string::String, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, + pub height: i32, + pub visibility: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RowMeta { + fn default() -> &'a RowMeta { + ::default_instance() + } +} + +impl RowMeta { + pub fn new() -> RowMeta { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string grid_id = 2; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // repeated .RowMeta.CellByFieldIdEntry cell_by_field_id = 3; + + + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { + &self.cell_by_field_id + } + pub fn clear_cell_by_field_id(&mut self) { + self.cell_by_field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { + self.cell_by_field_id = v; + } + + // Mutable pointer to the field. + pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { + &mut self.cell_by_field_id + } + + // Take field + pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { + ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) + } + + // int32 height = 4; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } + + // bool visibility = 5; + + + pub fn get_visibility(&self) -> bool { + self.visibility + } + pub fn clear_visibility(&mut self) { + self.visibility = false; + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.visibility = v; + } +} + +impl ::protobuf::Message for RowMeta { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 3 => { + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.visibility = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_id); + } + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); + if self.height != 0 { + my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); + } + if self.visibility != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_id)?; + } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; + if self.height != 0 { + os.write_int32(4, self.height)?; + } + if self.visibility != false { + os.write_bool(5, self.visibility)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RowMeta { + RowMeta::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &RowMeta| { &m.id }, + |m: &mut RowMeta| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &RowMeta| { &m.grid_id }, + |m: &mut RowMeta| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + "cell_by_field_id", + |m: &RowMeta| { &m.cell_by_field_id }, + |m: &mut RowMeta| { &mut m.cell_by_field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RowMeta| { &m.height }, + |m: &mut RowMeta| { &mut m.height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "visibility", + |m: &RowMeta| { &m.visibility }, + |m: &mut RowMeta| { &mut m.visibility }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RowMeta", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RowMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RowMeta::new) + } +} + +impl ::protobuf::Clear for RowMeta { + fn clear(&mut self) { + self.id.clear(); + self.grid_id.clear(); + self.cell_by_field_id.clear(); + self.height = 0; + self.visibility = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RowMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RowMeta { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct CellMeta { + // message fields + pub id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + pub data: ::protobuf::SingularPtrField, + pub height: i32, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellMeta { + fn default() -> &'a CellMeta { + ::default_instance() + } +} + +impl CellMeta { + pub fn new() -> CellMeta { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string row_id = 2; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // string field_id = 3; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // .AnyData data = 4; + + + pub fn get_data(&self) -> &AnyData { + self.data.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + pub fn has_data(&self) -> bool { + self.data.is_some() + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: AnyData) { + self.data = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut AnyData { + if self.data.is_none() { + self.data.set_default(); + } + self.data.as_mut().unwrap() + } + + // Take field + pub fn take_data(&mut self) -> AnyData { + self.data.take().unwrap_or_else(|| AnyData::new()) + } + + // int32 height = 5; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } +} + +impl ::protobuf::Message for CellMeta { + fn is_initialized(&self) -> bool { + for v in &self.data { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.row_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.field_id); + } + if let Some(ref v) = self.data.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.row_id.is_empty() { + os.write_string(2, &self.row_id)?; + } + if !self.field_id.is_empty() { + os.write_string(3, &self.field_id)?; + } + if let Some(ref v) = self.data.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if self.height != 0 { + os.write_int32(5, self.height)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CellMeta { + CellMeta::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &CellMeta| { &m.id }, + |m: &mut CellMeta| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellMeta| { &m.row_id }, + |m: &mut CellMeta| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellMeta| { &m.field_id }, + |m: &mut CellMeta| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "data", + |m: &CellMeta| { &m.data }, + |m: &mut CellMeta| { &mut m.data }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &CellMeta| { &m.height }, + |m: &mut CellMeta| { &mut m.height }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellMeta", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellMeta::new) + } +} + +impl ::protobuf::Clear for CellMeta { + fn clear(&mut self) { + self.id.clear(); + self.row_id.clear(); + self.field_id.clear(); + self.data.clear(); + self.height = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellMeta { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum FieldType { + RichText = 0, + Number = 1, + DateTime = 2, + SingleSelect = 3, + MultiSelect = 4, + Checkbox = 5, +} + +impl ::protobuf::ProtobufEnum for FieldType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(FieldType::RichText), + 1 => ::std::option::Option::Some(FieldType::Number), + 2 => ::std::option::Option::Some(FieldType::DateTime), + 3 => ::std::option::Option::Some(FieldType::SingleSelect), + 4 => ::std::option::Option::Some(FieldType::MultiSelect), + 5 => ::std::option::Option::Some(FieldType::Checkbox), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [FieldType] = &[ + FieldType::RichText, + FieldType::Number, + FieldType::DateTime, + FieldType::SingleSelect, + FieldType::MultiSelect, + FieldType::Checkbox, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("FieldType", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for FieldType { +} + +impl ::std::default::Default for FieldType { + fn default() -> Self { + FieldType::RichText + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldType { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\nmeta.proto\"a\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ + s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\ + dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\ + \x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\ + \x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\ + e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\ + \x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\ + \nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\ + \x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\ + \rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\ + tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\ + \x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\ + a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ + \x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\ + \x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ + \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ + \nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ + value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ + field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ + \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ + R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ + \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ + \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ + o3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs index 7b56c6cee8..d011b76000 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs @@ -3,3 +3,6 @@ mod grid; pub use grid::*; + +mod meta; +pub use meta::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 04e82bea78..b8577c6e3c 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -2,72 +2,34 @@ syntax = "proto3"; message Grid { string id = 1; - RepeatedFieldOrder field_orders = 2; - RepeatedRowOrder row_orders = 3; + repeated FieldOrder field_orders = 2; + repeated RowOrder row_orders = 3; } message FieldOrder { string field_id = 1; - bool visibility = 2; } message RepeatedFieldOrder { repeated FieldOrder items = 1; } -message Field { - string id = 1; - string name = 2; - string desc = 3; - FieldType field_type = 4; - bool frozen = 5; - int32 width = 6; - AnyData type_options = 7; -} -message RepeatedField { - repeated Field items = 1; -} -message AnyData { - string type_id = 1; - bytes value = 2; -} message RowOrder { - string grid_id = 1; - string row_id = 2; - bool visibility = 3; + string row_id = 1; } message RepeatedRowOrder { repeated RowOrder items = 1; } -message RawRow { - string id = 1; - string grid_id = 2; - map cell_by_field_id = 3; - int32 height = 4; -} -message RawCell { - string id = 1; - string row_id = 2; - string field_id = 3; - AnyData data = 4; - int32 height = 5; -} -message RepeatedRow { - repeated Row items = 1; -} message Row { string id = 1; map cell_by_field_id = 2; int32 height = 3; } +message RepeatedRow { + repeated Row items = 1; +} message Cell { string id = 1; string field_id = 2; string content = 3; } -message CellChangeset { - string id = 1; - string row_id = 2; - string field_id = 3; - string data = 4; -} message CreateGridPayload { string name = 1; } @@ -82,11 +44,3 @@ message QueryRowPayload { string grid_id = 1; RepeatedRowOrder row_orders = 2; } -enum FieldType { - RichText = 0; - Number = 1; - DateTime = 2; - SingleSelect = 3; - MultiSelect = 4; - Checkbox = 5; -} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto new file mode 100644 index 0000000000..24149d1fa0 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; + +message GridMeta { + string grid_id = 1; + repeated Field fields = 2; + repeated RowMeta rows = 3; +} +message GridBlock { + string id = 1; + repeated RowMeta rows = 2; +} +message Field { + string id = 1; + string name = 2; + string desc = 3; + FieldType field_type = 4; + bool frozen = 5; + bool visibility = 6; + int32 width = 7; + AnyData type_options = 8; +} +message RepeatedField { + repeated Field items = 1; +} +message AnyData { + string type_id = 1; + bytes value = 2; +} +message RowMeta { + string id = 1; + string grid_id = 2; + map cell_by_field_id = 3; + int32 height = 4; + bool visibility = 5; +} +message CellMeta { + string id = 1; + string row_id = 2; + string field_id = 3; + AnyData data = 4; + int32 height = 5; +} +enum FieldType { + RichText = 0; + Number = 1; + DateTime = 2; + SingleSelect = 3; + MultiSelect = 4; + Checkbox = 5; +} diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 287ffffa6b..203651a9a0 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -3,54 +3,36 @@ use flowy_grid_data_model::entities::*; #[test] fn grid_serde_test() { let grid_id = "1".to_owned(); - let field_orders = RepeatedFieldOrder { - items: vec![create_field_order("1")], - }; - let row_orders = RepeatedRowOrder { - items: vec![create_row_order(&grid_id, "1")], + let fields = vec![create_field("1")]; + let grid = GridMeta { + grid_id, + fields, + rows: vec![], }; - let grid = Grid { - id: grid_id, - field_orders, - row_orders, - }; - - let json = serde_json::to_string(&grid).unwrap(); - let grid2: Grid = serde_json::from_str(&json).unwrap(); - assert_eq!(grid, grid2); + let grid_1_json = serde_json::to_string(&grid).unwrap(); + let _: Grid = serde_json::from_str(&grid_1_json).unwrap(); assert_eq!( - json, - r#"{"id":"1","field_orders":[{"field_id":"1","visibility":false}],"row_orders":[{"grid_id":"1","row_id":"1","visibility":false}]}"# + grid_1_json, + r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"rows":[]}"# ) } #[test] fn grid_default_serde_test() { let grid_id = "1".to_owned(); - let grid = Grid { - id: grid_id, - field_orders: RepeatedFieldOrder::default(), - row_orders: RepeatedRowOrder::default(), + let grid = GridMeta { + grid_id, + fields: vec![], + rows: vec![], }; let json = serde_json::to_string(&grid).unwrap(); - assert_eq!(json, r#"{"id":"1","field_orders":[],"row_orders":[]}"#) + assert_eq!(json, r#"{"id":"1","fields":[],"row_orders":[]}"#) } -fn create_field_order(field_id: &str) -> FieldOrder { - FieldOrder { - field_id: field_id.to_owned(), - visibility: false, - } -} - -fn create_row_order(grid_id: &str, row_id: &str) -> RowOrder { - RowOrder { - grid_id: grid_id.to_string(), - row_id: row_id.to_string(), - visibility: false, - } +fn create_field(field_id: &str) -> Field { + Field::new(field_id, "Text Field", "", FieldType::RichText) } #[allow(dead_code)] From 7ac6a1dc89b9e767f261c5fbb774b0794b0b6809 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 17:14:10 +0800 Subject: [PATCH 027/179] chore: rename struct --- .../lib/startup/home_deps_resolver.dart | 1 + .../grid/cell_bloc/checkbox_cell_bloc.dart | 1 + .../grid/cell_bloc/date_cell_bloc.dart | 1 + .../grid/cell_bloc/number_cell_bloc.dart | 1 + .../grid/cell_bloc/selection_cell_bloc.dart | 1 + .../grid/cell_bloc/text_cell_bloc.dart | 1 + .../application/grid/column_bloc.dart | 2 +- .../lib/workspace/application/grid/data.dart | 1 + .../application/grid/grid_service.dart | 1 + .../plugins/grid/src/grid_page.dart | 2 +- .../plugins/grid/src/layout/layout.dart | 2 +- .../src/widgets/content/cell_builder.dart | 1 + .../src/widgets/content/cell_container.dart | 1 - .../src/widgets/content/checkbox_cell.dart | 1 + .../grid/src/widgets/content/date_cell.dart | 1 + .../grid/src/widgets/content/number_cell.dart | 1 + .../src/widgets/content/selection_cell.dart | 1 + .../grid/src/widgets/content/text_cell.dart | 1 + .../grid/src/widgets/header/header.dart | 2 +- .../grid/src/widgets/header/header_cell.dart | 2 +- .../flowy_sdk/lib/dispatch/dispatch.dart | 1 - .../flowy-collaboration/protobuf.dart | 2 +- .../text_block_info.pb.dart | 412 ++++++++++++++++++ .../text_block_info.pbenum.dart | 7 + .../text_block_info.pbjson.dart | 78 ++++ .../text_block_info.pbserver.dart | 9 + .../flowy-grid-data-model/meta.pb.dart | 119 ++++- .../flowy-grid-data-model/meta.pbjson.dart | 26 +- .../src/{block_editor.rs => editor.rs} | 20 +- .../rust-lib/flowy-block/src/event_handler.rs | 22 +- .../rust-lib/flowy-block/src/event_map.rs | 4 +- frontend/rust-lib/flowy-block/src/lib.rs | 12 +- frontend/rust-lib/flowy-block/src/manager.rs | 89 ++-- frontend/rust-lib/flowy-block/src/queue.rs | 6 +- .../rust-lib/flowy-block/src/web_socket.rs | 20 +- .../flowy-block/tests/document/edit_script.rs | 6 +- .../2022-03-04-101530_flowy-grid/down.sql | 3 +- .../2022-03-04-101530_flowy-grid/up.sql | 9 + .../src/services/view/controller.rs | 4 +- .../flowy-folder/tests/workspace/helper.rs | 6 +- .../flowy-folder/tests/workspace/script.rs | 4 +- .../flowy-grid/src/services/grid_builder.rs | 2 +- .../flowy-net/src/http_server/document.rs | 20 +- .../flowy-net/src/local_server/persistence.rs | 6 +- .../flowy-net/src/local_server/server.rs | 10 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 35 +- .../flowy-sdk/src/deps_resolve/mod.rs | 4 +- .../{block_deps.rs => text_block_deps.rs} | 20 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 28 +- frontend/rust-lib/flowy-sdk/src/module.rs | 18 +- .../src/cache/disk/folder_rev_impl.rs | 0 .../src/cache/disk/grid_rev_impl.rs | 0 .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 11 +- .../{sql_impl.rs => text_block_rev_impl.rs} | 6 +- frontend/rust-lib/flowy-sync/src/cache/mod.rs | 327 +------------- frontend/rust-lib/flowy-sync/src/lib.rs | 2 + .../flowy-sync/src/rev_persistence.rs | 322 ++++++++++++++ .../src/client_grid/block_pad.rs | 115 +++++ .../src/client_grid/grid_pad.rs | 20 +- .../src/client_grid/mod.rs | 2 + .../flowy-collaboration/src/entities/mod.rs | 2 +- .../{document_info.rs => text_block_info.rs} | 30 +- .../src/protobuf/model/mod.rs | 6 +- .../{document_info.rs => text_block_info.rs} | 244 +++++------ ...ument_info.proto => text_block_info.proto} | 10 +- .../src/server_document/document_manager.rs | 10 +- shared-lib/flowy-collaboration/src/util.rs | 14 +- .../src/entities/grid.rs | 4 +- .../src/entities/meta.rs | 17 +- .../src/protobuf/model/meta.rs | 385 ++++++++++++---- .../src/protobuf/proto/meta.proto | 9 +- .../flowy-grid-data-model/tests/serde_test.rs | 10 +- 72 files changed, 1788 insertions(+), 785 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart rename frontend/rust-lib/flowy-block/src/{block_editor.rs => editor.rs} (95%) rename frontend/rust-lib/flowy-sdk/src/deps_resolve/{block_deps.rs => text_block_deps.rs} (85%) create mode 100644 frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs create mode 100644 frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs rename frontend/rust-lib/flowy-sync/src/cache/disk/{sql_impl.rs => text_block_rev_impl.rs} (98%) create mode 100644 frontend/rust-lib/flowy-sync/src/rev_persistence.rs create mode 100644 shared-lib/flowy-collaboration/src/client_grid/block_pad.rs rename shared-lib/flowy-collaboration/src/entities/{document_info.rs => text_block_info.rs} (78%) rename shared-lib/flowy-collaboration/src/protobuf/model/{document_info.rs => text_block_info.rs} (85%) rename shared-lib/flowy-collaboration/src/protobuf/proto/{document_info.proto => text_block_info.proto} (76%) diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 5b91d8a545..367390efa0 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -13,6 +13,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 8f0de7fb32..a4ef372a8b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index c8b5e97f2d..f24a9ee769 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index b216550a81..4959b67902 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 5e7a6e8e22..615c56f01e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index cce4ff9224..0aa6c8e1a9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart index 39badc922a..6313920223 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index c32f87f1a2..96f89c9eb0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,5 +1,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:equatable/equatable.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridInfo { List rows; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index e519b0a90d..a3f7f68760 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,6 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridService { Future> openGrid({required String gridId}) async { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 7435ea0e5f..46c14d9b8d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; import 'package:styled_widget/styled_widget.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 3f076fc89f..14f4a672cf 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'sizes.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 754678ef8e..0abfc26047 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 56cc4e174f..0bfcc10caa 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/theme.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index d3d2b57735..ffa94d428e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index e1661fdffa..f36bdb386c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 86b9863019..143f741b15 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 047cff7475..6dc2a1922a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 7661ddc22f..eef2f79195 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 83d24535f4..6a2adc619e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index aacdcd251e..6217c9c344 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart index f26efb17e4..715b9b2f4f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -22,7 +22,6 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-block/protobuf.dart'; -import 'package:flowy_sdk/protobuf/flowy-collaboration/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; // ignore: unused_import diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart index 050f20adc0..78a7a563db 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart @@ -1,5 +1,5 @@ // Auto-generated, do not edit export './folder_info.pb.dart'; export './ws_data.pb.dart'; +export './text_block_info.pb.dart'; export './revision.pb.dart'; -export './document_info.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart new file mode 100644 index 0000000000..43d315d340 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart @@ -0,0 +1,412 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +import 'revision.pb.dart' as $0; + +class CreateTextBlockParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateTextBlockParams', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) + ..hasRequiredFields = false + ; + + CreateTextBlockParams._() : super(); + factory CreateTextBlockParams({ + $core.String? id, + $0.RepeatedRevision? revisions, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (revisions != null) { + _result.revisions = revisions; + } + return _result; + } + factory CreateTextBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateTextBlockParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CreateTextBlockParams clone() => CreateTextBlockParams()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateTextBlockParams copyWith(void Function(CreateTextBlockParams) updates) => super.copyWith((message) => updates(message as CreateTextBlockParams)) as CreateTextBlockParams; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateTextBlockParams create() => CreateTextBlockParams._(); + CreateTextBlockParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateTextBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateTextBlockParams? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $0.RepeatedRevision get revisions => $_getN(1); + @$pb.TagNumber(2) + set revisions($0.RepeatedRevision v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasRevisions() => $_has(1); + @$pb.TagNumber(2) + void clearRevisions() => clearField(2); + @$pb.TagNumber(2) + $0.RepeatedRevision ensureRevisions() => $_ensure(1); +} + +class TextBlockInfo extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockInfo', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'text') + ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') + ..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'baseRevId') + ..hasRequiredFields = false + ; + + TextBlockInfo._() : super(); + factory TextBlockInfo({ + $core.String? blockId, + $core.String? text, + $fixnum.Int64? revId, + $fixnum.Int64? baseRevId, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (text != null) { + _result.text = text; + } + if (revId != null) { + _result.revId = revId; + } + if (baseRevId != null) { + _result.baseRevId = baseRevId; + } + return _result; + } + factory TextBlockInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TextBlockInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TextBlockInfo clone() => TextBlockInfo()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TextBlockInfo copyWith(void Function(TextBlockInfo) updates) => super.copyWith((message) => updates(message as TextBlockInfo)) as TextBlockInfo; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TextBlockInfo create() => TextBlockInfo._(); + TextBlockInfo createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TextBlockInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TextBlockInfo? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get text => $_getSZ(1); + @$pb.TagNumber(2) + set text($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasText() => $_has(1); + @$pb.TagNumber(2) + void clearText() => clearField(2); + + @$pb.TagNumber(3) + $fixnum.Int64 get revId => $_getI64(2); + @$pb.TagNumber(3) + set revId($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(3) + $core.bool hasRevId() => $_has(2); + @$pb.TagNumber(3) + void clearRevId() => clearField(3); + + @$pb.TagNumber(4) + $fixnum.Int64 get baseRevId => $_getI64(3); + @$pb.TagNumber(4) + set baseRevId($fixnum.Int64 v) { $_setInt64(3, v); } + @$pb.TagNumber(4) + $core.bool hasBaseRevId() => $_has(3); + @$pb.TagNumber(4) + void clearBaseRevId() => clearField(4); +} + +class ResetTextBlockParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ResetTextBlockParams', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) + ..hasRequiredFields = false + ; + + ResetTextBlockParams._() : super(); + factory ResetTextBlockParams({ + $core.String? blockId, + $0.RepeatedRevision? revisions, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (revisions != null) { + _result.revisions = revisions; + } + return _result; + } + factory ResetTextBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ResetTextBlockParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ResetTextBlockParams clone() => ResetTextBlockParams()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ResetTextBlockParams copyWith(void Function(ResetTextBlockParams) updates) => super.copyWith((message) => updates(message as ResetTextBlockParams)) as ResetTextBlockParams; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ResetTextBlockParams create() => ResetTextBlockParams._(); + ResetTextBlockParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ResetTextBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ResetTextBlockParams? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $0.RepeatedRevision get revisions => $_getN(1); + @$pb.TagNumber(2) + set revisions($0.RepeatedRevision v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasRevisions() => $_has(1); + @$pb.TagNumber(2) + void clearRevisions() => clearField(2); + @$pb.TagNumber(2) + $0.RepeatedRevision ensureRevisions() => $_ensure(1); +} + +class TextBlockDelta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockDelta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaStr') + ..hasRequiredFields = false + ; + + TextBlockDelta._() : super(); + factory TextBlockDelta({ + $core.String? blockId, + $core.String? deltaStr, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (deltaStr != null) { + _result.deltaStr = deltaStr; + } + return _result; + } + factory TextBlockDelta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TextBlockDelta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TextBlockDelta clone() => TextBlockDelta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TextBlockDelta copyWith(void Function(TextBlockDelta) updates) => super.copyWith((message) => updates(message as TextBlockDelta)) as TextBlockDelta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TextBlockDelta create() => TextBlockDelta._(); + TextBlockDelta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TextBlockDelta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TextBlockDelta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get deltaStr => $_getSZ(1); + @$pb.TagNumber(2) + set deltaStr($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasDeltaStr() => $_has(1); + @$pb.TagNumber(2) + void clearDeltaStr() => clearField(2); +} + +class NewDocUser extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NewDocUser', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId') + ..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') + ..hasRequiredFields = false + ; + + NewDocUser._() : super(); + factory NewDocUser({ + $core.String? userId, + $fixnum.Int64? revId, + $core.String? docId, + }) { + final _result = create(); + if (userId != null) { + _result.userId = userId; + } + if (revId != null) { + _result.revId = revId; + } + if (docId != null) { + _result.docId = docId; + } + return _result; + } + factory NewDocUser.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NewDocUser.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NewDocUser clone() => NewDocUser()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NewDocUser copyWith(void Function(NewDocUser) updates) => super.copyWith((message) => updates(message as NewDocUser)) as NewDocUser; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NewDocUser create() => NewDocUser._(); + NewDocUser createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NewDocUser getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NewDocUser? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get userId => $_getSZ(0); + @$pb.TagNumber(1) + set userId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasUserId() => $_has(0); + @$pb.TagNumber(1) + void clearUserId() => clearField(1); + + @$pb.TagNumber(2) + $fixnum.Int64 get revId => $_getI64(1); + @$pb.TagNumber(2) + set revId($fixnum.Int64 v) { $_setInt64(1, v); } + @$pb.TagNumber(2) + $core.bool hasRevId() => $_has(1); + @$pb.TagNumber(2) + void clearRevId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get docId => $_getSZ(2); + @$pb.TagNumber(3) + set docId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDocId() => $_has(2); + @$pb.TagNumber(3) + void clearDocId() => clearField(3); +} + +class TextBlockId extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockId', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') + ..hasRequiredFields = false + ; + + TextBlockId._() : super(); + factory TextBlockId({ + $core.String? value, + }) { + final _result = create(); + if (value != null) { + _result.value = value; + } + return _result; + } + factory TextBlockId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TextBlockId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TextBlockId clone() => TextBlockId()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TextBlockId copyWith(void Function(TextBlockId) updates) => super.copyWith((message) => updates(message as TextBlockId)) as TextBlockId; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TextBlockId create() => TextBlockId._(); + TextBlockId createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TextBlockId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TextBlockId? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get value => $_getSZ(0); + @$pb.TagNumber(1) + set value($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasValue() => $_has(0); + @$pb.TagNumber(1) + void clearValue() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart new file mode 100644 index 0000000000..20728d1388 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart new file mode 100644 index 0000000000..794b4ca433 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart @@ -0,0 +1,78 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use createTextBlockParamsDescriptor instead') +const CreateTextBlockParams$json = const { + '1': 'CreateTextBlockParams', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, + ], +}; + +/// Descriptor for `CreateTextBlockParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createTextBlockParamsDescriptor = $convert.base64Decode('ChVDcmVhdGVUZXh0QmxvY2tQYXJhbXMSDgoCaWQYASABKAlSAmlkEi8KCXJldmlzaW9ucxgCIAEoCzIRLlJlcGVhdGVkUmV2aXNpb25SCXJldmlzaW9ucw=='); +@$core.Deprecated('Use textBlockInfoDescriptor instead') +const TextBlockInfo$json = const { + '1': 'TextBlockInfo', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'text', '3': 2, '4': 1, '5': 9, '10': 'text'}, + const {'1': 'rev_id', '3': 3, '4': 1, '5': 3, '10': 'revId'}, + const {'1': 'base_rev_id', '3': 4, '4': 1, '5': 3, '10': 'baseRevId'}, + ], +}; + +/// Descriptor for `TextBlockInfo`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List textBlockInfoDescriptor = $convert.base64Decode('Cg1UZXh0QmxvY2tJbmZvEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhIKBHRleHQYAiABKAlSBHRleHQSFQoGcmV2X2lkGAMgASgDUgVyZXZJZBIeCgtiYXNlX3Jldl9pZBgEIAEoA1IJYmFzZVJldklk'); +@$core.Deprecated('Use resetTextBlockParamsDescriptor instead') +const ResetTextBlockParams$json = const { + '1': 'ResetTextBlockParams', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, + ], +}; + +/// Descriptor for `ResetTextBlockParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List resetTextBlockParamsDescriptor = $convert.base64Decode('ChRSZXNldFRleHRCbG9ja1BhcmFtcxIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIvCglyZXZpc2lvbnMYAiABKAsyES5SZXBlYXRlZFJldmlzaW9uUglyZXZpc2lvbnM='); +@$core.Deprecated('Use textBlockDeltaDescriptor instead') +const TextBlockDelta$json = const { + '1': 'TextBlockDelta', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'delta_str', '3': 2, '4': 1, '5': 9, '10': 'deltaStr'}, + ], +}; + +/// Descriptor for `TextBlockDelta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List textBlockDeltaDescriptor = $convert.base64Decode('Cg5UZXh0QmxvY2tEZWx0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIbCglkZWx0YV9zdHIYAiABKAlSCGRlbHRhU3Ry'); +@$core.Deprecated('Use newDocUserDescriptor instead') +const NewDocUser$json = const { + '1': 'NewDocUser', + '2': const [ + const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'}, + const {'1': 'rev_id', '3': 2, '4': 1, '5': 3, '10': 'revId'}, + const {'1': 'doc_id', '3': 3, '4': 1, '5': 9, '10': 'docId'}, + ], +}; + +/// Descriptor for `NewDocUser`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List newDocUserDescriptor = $convert.base64Decode('CgpOZXdEb2NVc2VyEhcKB3VzZXJfaWQYASABKAlSBnVzZXJJZBIVCgZyZXZfaWQYAiABKANSBXJldklkEhUKBmRvY19pZBgDIAEoCVIFZG9jSWQ='); +@$core.Deprecated('Use textBlockIdDescriptor instead') +const TextBlockId$json = const { + '1': 'TextBlockId', + '2': const [ + const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, + ], +}; + +/// Descriptor for `TextBlockId`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List textBlockIdDescriptor = $convert.base64Decode('CgtUZXh0QmxvY2tJZBIUCgV2YWx1ZRgBIAEoCVIFdmFsdWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart new file mode 100644 index 0000000000..5c81f4cb56 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'text_block_info.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 11370c1fd2..4ac91c7ff1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: Block.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? rows, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage { if (fields != null) { _result.fields.addAll(fields); } - if (rows != null) { - _result.rows.addAll(rows); + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } @@ -73,50 +73,55 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get rows => $_getList(2); + $core.List get blocks => $_getList(2); } -class GridBlock extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) +class Block extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Block', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) ..hasRequiredFields = false ; - GridBlock._() : super(); - factory GridBlock({ + Block._() : super(); + factory Block({ $core.String? id, - $core.Iterable? rows, + $core.int? startRowIndex, + $core.int? rowCount, }) { final _result = create(); if (id != null) { _result.id = id; } - if (rows != null) { - _result.rows.addAll(rows); + if (startRowIndex != null) { + _result.startRowIndex = startRowIndex; + } + if (rowCount != null) { + _result.rowCount = rowCount; } return _result; } - factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory Block.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Block.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - GridBlock clone() => GridBlock()..mergeFromMessage(this); + Block clone() => Block()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use + Block copyWith(void Function(Block) updates) => super.copyWith((message) => updates(message as Block)) as Block; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GridBlock create() => GridBlock._(); - GridBlock createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static Block create() => Block._(); + Block createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlock? _defaultInstance; + static Block getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Block? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -127,6 +132,76 @@ class GridBlock extends $pb.GeneratedMessage { @$pb.TagNumber(1) void clearId() => clearField(1); + @$pb.TagNumber(2) + $core.int get startRowIndex => $_getIZ(1); + @$pb.TagNumber(2) + set startRowIndex($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasStartRowIndex() => $_has(1); + @$pb.TagNumber(2) + void clearStartRowIndex() => clearField(2); + + @$pb.TagNumber(3) + $core.int get rowCount => $_getIZ(2); + @$pb.TagNumber(3) + set rowCount($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowCount() => $_has(2); + @$pb.TagNumber(3) + void clearRowCount() => clearField(3); +} + +class BlockMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + BlockMeta._() : super(); + factory BlockMeta({ + $core.String? blockId, + $core.Iterable? rows, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory BlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BlockMeta clone() => BlockMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BlockMeta copyWith(void Function(BlockMeta) updates) => super.copyWith((message) => updates(message as BlockMeta)) as BlockMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BlockMeta create() => BlockMeta._(); + BlockMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static BlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static BlockMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + @$pb.TagNumber(2) $core.List get rows => $_getList(1); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index eb41930ba4..d0d94fd269 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,23 +29,35 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, - const {'1': 'rows', '3': 3, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.Block', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw=='); -@$core.Deprecated('Use gridBlockDescriptor instead') -const GridBlock$json = const { - '1': 'GridBlock', +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIeCgZibG9ja3MYAyADKAsyBi5CbG9ja1IGYmxvY2tz'); +@$core.Deprecated('Use blockDescriptor instead') +const Block$json = const { + '1': 'Block', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, + const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, + ], +}; + +/// Descriptor for `Block`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blockDescriptor = $convert.base64Decode('CgVCbG9jaxIOCgJpZBgBIAEoCVICaWQSJgoPc3RhcnRfcm93X2luZGV4GAIgASgFUg1zdGFydFJvd0luZGV4EhsKCXJvd19jb3VudBgDIAEoBVIIcm93Q291bnQ='); +@$core.Deprecated('Use blockMetaDescriptor instead') +const BlockMeta$json = const { + '1': 'BlockMeta', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, ], }; -/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); +/// Descriptor for `BlockMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blockMetaDescriptor = $convert.base64Decode('CglCbG9ja01ldGESGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSHAoEcm93cxgCIAMoCzIILlJvd01ldGFSBHJvd3M='); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', diff --git a/frontend/rust-lib/flowy-block/src/block_editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs similarity index 95% rename from frontend/rust-lib/flowy-block/src/block_editor.rs rename to frontend/rust-lib/flowy-block/src/editor.rs index f8b0f87c6b..d7977c19db 100644 --- a/frontend/rust-lib/flowy-block/src/block_editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -3,12 +3,12 @@ use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; use crate::{ errors::FlowyError, queue::{EditBlockQueue, EditorCommand}, - BlockUser, + TextBlockUser, }; use bytes::Bytes; use flowy_collaboration::entities::ws_data::ServerRevisionWSData; use flowy_collaboration::{ - entities::{document_info::BlockInfo, revision::Revision}, + entities::{revision::Revision, text_block_info::TextBlockInfo}, errors::CollaborateResult, util::make_delta_from_revisions, }; @@ -24,7 +24,7 @@ use lib_ws::WSConnectState; use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; -pub struct ClientBlockEditor { +pub struct ClientTextBlockEditor { pub doc_id: String, #[allow(dead_code)] rev_manager: Arc, @@ -32,10 +32,10 @@ pub struct ClientBlockEditor { edit_cmd_tx: EditorCommandSender, } -impl ClientBlockEditor { +impl ClientTextBlockEditor { pub(crate) async fn new( doc_id: &str, - user: Arc, + user: Arc, mut rev_manager: RevisionManager, rev_web_socket: Arc, cloud_service: Arc, @@ -174,7 +174,7 @@ impl ClientBlockEditor { } } -impl std::ops::Drop for ClientBlockEditor { +impl std::ops::Drop for ClientTextBlockEditor { fn drop(&mut self) { tracing::trace!("{} ClientBlockEditor was dropped", self.doc_id) } @@ -182,7 +182,7 @@ impl std::ops::Drop for ClientBlockEditor { // The edit queue will exit after the EditorCommandSender was dropped. fn spawn_edit_queue( - user: Arc, + user: Arc, rev_manager: Arc, delta: RichTextDelta, ) -> EditorCommandSender { @@ -193,7 +193,7 @@ fn spawn_edit_queue( } #[cfg(feature = "flowy_unit_test")] -impl ClientBlockEditor { +impl ClientTextBlockEditor { pub async fn doc_json(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); let msg = EditorCommand::ReadDeltaStr { ret }; @@ -217,14 +217,14 @@ impl ClientBlockEditor { struct BlockInfoBuilder(); impl RevisionObjectBuilder for BlockInfoBuilder { - type Output = BlockInfo; + type Output = TextBlockInfo; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { let (base_rev_id, rev_id) = revisions.last().unwrap().pair_rev_id(); let mut delta = make_delta_from_revisions(revisions)?; correct_delta(&mut delta); - Result::::Ok(BlockInfo { + Result::::Ok(TextBlockInfo { block_id: object_id.to_owned(), text: delta.to_delta_str(), rev_id, diff --git a/frontend/rust-lib/flowy-block/src/event_handler.rs b/frontend/rust-lib/flowy-block/src/event_handler.rs index 39761d3d7c..1457fc2992 100644 --- a/frontend/rust-lib/flowy-block/src/event_handler.rs +++ b/frontend/rust-lib/flowy-block/src/event_handler.rs @@ -1,28 +1,28 @@ use crate::entities::{ExportData, ExportParams, ExportPayload}; -use crate::BlockManager; -use flowy_collaboration::entities::document_info::{BlockDelta, BlockId}; +use crate::TextBlockManager; +use flowy_collaboration::entities::text_block_info::{TextBlockDelta, TextBlockId}; use flowy_error::FlowyError; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::convert::TryInto; use std::sync::Arc; pub(crate) async fn get_block_data_handler( - data: Data, - manager: AppData>, -) -> DataResult { - let block_id: BlockId = data.into_inner(); + data: Data, + manager: AppData>, +) -> DataResult { + let block_id: TextBlockId = data.into_inner(); let editor = manager.open_block(&block_id).await?; let delta_str = editor.delta_str().await?; - data_result(BlockDelta { + data_result(TextBlockDelta { block_id: block_id.into(), delta_str, }) } pub(crate) async fn apply_delta_handler( - data: Data, - manager: AppData>, -) -> DataResult { + data: Data, + manager: AppData>, +) -> DataResult { let block_delta = manager.receive_local_delta(data.into_inner()).await?; data_result(block_delta) } @@ -30,7 +30,7 @@ pub(crate) async fn apply_delta_handler( #[tracing::instrument(skip(data, manager), err)] pub(crate) async fn export_handler( data: Data, - manager: AppData>, + manager: AppData>, ) -> DataResult { let params: ExportParams = data.into_inner().try_into()?; let editor = manager.open_block(¶ms.view_id).await?; diff --git a/frontend/rust-lib/flowy-block/src/event_map.rs b/frontend/rust-lib/flowy-block/src/event_map.rs index f0cfda219c..8342102bf5 100644 --- a/frontend/rust-lib/flowy-block/src/event_map.rs +++ b/frontend/rust-lib/flowy-block/src/event_map.rs @@ -1,11 +1,11 @@ use crate::event_handler::*; -use crate::BlockManager; +use crate::TextBlockManager; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; use lib_dispatch::prelude::Module; use std::sync::Arc; use strum_macros::Display; -pub fn create(block_manager: Arc) -> Module { +pub fn create(block_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(block_manager); module = module diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-block/src/lib.rs index 8f15fd7e31..b75ed7e147 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-block/src/lib.rs @@ -1,4 +1,4 @@ -pub mod block_editor; +pub mod editor; mod entities; mod event_handler; pub mod event_map; @@ -15,13 +15,15 @@ pub mod errors { pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; use crate::errors::FlowyError; -use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; +use flowy_collaboration::entities::text_block_info::{ + CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo, +}; use lib_infra::future::FutureResult; pub trait BlockCloudService: Send + Sync { - fn create_block(&self, token: &str, params: CreateBlockParams) -> FutureResult<(), FlowyError>; + fn create_block(&self, token: &str, params: CreateTextBlockParams) -> FutureResult<(), FlowyError>; - fn read_block(&self, token: &str, params: BlockId) -> FutureResult, FlowyError>; + fn read_block(&self, token: &str, params: TextBlockId) -> FutureResult, FlowyError>; - fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError>; + fn update_block(&self, token: &str, params: ResetTextBlockParams) -> FutureResult<(), FlowyError>; } diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index 17ea23c7bb..091ca31bec 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -1,9 +1,9 @@ -use crate::{block_editor::ClientBlockEditor, errors::FlowyError, BlockCloudService}; +use crate::{editor::ClientTextBlockEditor, errors::FlowyError, BlockCloudService}; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::entities::{ - document_info::{BlockDelta, BlockId}, revision::{md5, RepeatedRevision, Revision}, + text_block_info::{TextBlockDelta, TextBlockId}, ws_data::ServerRevisionWSData, }; use flowy_database::ConnectionPool; @@ -12,43 +12,42 @@ use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, Rev use lib_infra::future::FutureResult; use std::{convert::TryInto, sync::Arc}; -pub trait BlockUser: Send + Sync { +pub trait TextBlockUser: Send + Sync { fn user_dir(&self) -> Result; fn user_id(&self) -> Result; fn token(&self) -> Result; fn db_pool(&self) -> Result, FlowyError>; } -pub struct BlockManager { +pub struct TextBlockManager { cloud_service: Arc, rev_web_socket: Arc, - block_editors: Arc, - block_user: Arc, + editor_map: Arc, + user: Arc, } -impl BlockManager { +impl TextBlockManager { pub fn new( cloud_service: Arc, - block_user: Arc, + text_block_user: Arc, rev_web_socket: Arc, ) -> Self { - let block_editors = Arc::new(BlockEditors::new()); Self { cloud_service, rev_web_socket, - block_editors, - block_user, + editor_map: Arc::new(TextBlockEditorMap::new()), + user: text_block_user, } } pub fn init(&self) -> FlowyResult<()> { - listen_ws_state_changed(self.rev_web_socket.clone(), self.block_editors.clone()); + listen_ws_state_changed(self.rev_web_socket.clone(), self.editor_map.clone()); Ok(()) } #[tracing::instrument(level = "debug", skip(self, block_id), fields(block_id), err)] - pub async fn open_block>(&self, block_id: T) -> Result, FlowyError> { + pub async fn open_block>(&self, block_id: T) -> Result, FlowyError> { let block_id = block_id.as_ref(); tracing::Span::current().record("block_id", &block_id); self.get_block_editor(block_id).await @@ -58,7 +57,7 @@ impl BlockManager { pub fn close_block>(&self, block_id: T) -> Result<(), FlowyError> { let block_id = block_id.as_ref(); tracing::Span::current().record("block_id", &block_id); - self.block_editors.remove(block_id); + self.editor_map.remove(block_id); Ok(()) } @@ -66,16 +65,16 @@ impl BlockManager { pub fn delete_block>(&self, doc_id: T) -> Result<(), FlowyError> { let doc_id = doc_id.as_ref(); tracing::Span::current().record("doc_id", &doc_id); - self.block_editors.remove(doc_id); + self.editor_map.remove(doc_id); Ok(()) } #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)] - pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result { + pub async fn receive_local_delta(&self, delta: TextBlockDelta) -> Result { let editor = self.get_block_editor(&delta.block_id).await?; let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?; let document_json = editor.delta_str().await?; - Ok(BlockDelta { + Ok(TextBlockDelta { block_id: delta.block_id.clone(), delta_str: document_json, }) @@ -83,7 +82,7 @@ impl BlockManager { pub async fn create_block>(&self, doc_id: T, revisions: RepeatedRevision) -> FlowyResult<()> { let doc_id = doc_id.as_ref().to_owned(); - let db_pool = self.block_user.db_pool()?; + let db_pool = self.user.db_pool()?; // Maybe we could save the block to disk without creating the RevisionManager let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?; let _ = rev_manager.reset_object(revisions).await?; @@ -93,9 +92,9 @@ impl BlockManager { pub async fn receive_ws_data(&self, data: Bytes) { let result: Result = data.try_into(); match result { - Ok(data) => match self.block_editors.get(&data.object_id) { + Ok(data) => match self.editor_map.get(&data.object_id) { None => tracing::error!("Can't find any source handler for {:?}-{:?}", data.object_id, data.ty), - Some(block_editor) => match block_editor.receive_ws_data(data).await { + Some(editor) => match editor.receive_ws_data(data).await { Ok(_) => {} Err(e) => tracing::error!("{}", e), }, @@ -107,11 +106,11 @@ impl BlockManager { } } -impl BlockManager { - async fn get_block_editor(&self, block_id: &str) -> FlowyResult> { - match self.block_editors.get(block_id) { +impl TextBlockManager { + async fn get_block_editor(&self, block_id: &str) -> FlowyResult> { + match self.editor_map.get(block_id) { None => { - let db_pool = self.block_user.db_pool()?; + let db_pool = self.user.db_pool()?; self.make_block_editor(block_id, db_pool).await } Some(editor) => Ok(editor), @@ -122,36 +121,36 @@ impl BlockManager { &self, block_id: &str, pool: Arc, - ) -> Result, FlowyError> { - let user = self.block_user.clone(); - let token = self.block_user.token()?; + ) -> Result, FlowyError> { + let user = self.user.clone(); + let token = self.user.token()?; let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?; - let cloud_service = Arc::new(BlockRevisionCloudService { + let cloud_service = Arc::new(TextBlockRevisionCloudService { token, server: self.cloud_service.clone(), }); let doc_editor = - ClientBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?; - self.block_editors.insert(block_id, &doc_editor); + ClientTextBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?; + self.editor_map.insert(block_id, &doc_editor); Ok(doc_editor) } fn make_block_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { - let user_id = self.block_user.user_id()?; + let user_id = self.user.user_id()?; let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool)); Ok(RevisionManager::new(&user_id, doc_id, rev_persistence)) } } -struct BlockRevisionCloudService { +struct TextBlockRevisionCloudService { token: String, server: Arc, } -impl RevisionCloudService for BlockRevisionCloudService { +impl RevisionCloudService for TextBlockRevisionCloudService { #[tracing::instrument(level = "trace", skip(self))] fn fetch_object(&self, user_id: &str, object_id: &str) -> FutureResult, FlowyError> { - let params: BlockId = object_id.to_string().into(); + let params: TextBlockId = object_id.to_string().into(); let server = self.server.clone(); let token = self.token.clone(); let user_id = user_id.to_string(); @@ -177,32 +176,24 @@ impl RevisionCloudService for BlockRevisionCloudService { } } -pub struct BlockEditors { - inner: DashMap>, +pub struct TextBlockEditorMap { + inner: DashMap>, } -impl BlockEditors { +impl TextBlockEditorMap { fn new() -> Self { Self { inner: DashMap::new() } } - pub(crate) fn insert(&self, block_id: &str, doc: &Arc) { + pub(crate) fn insert(&self, block_id: &str, doc: &Arc) { if self.inner.contains_key(block_id) { log::warn!("Doc:{} already exists in cache", block_id); } self.inner.insert(block_id.to_string(), doc.clone()); } - pub(crate) fn contains(&self, block_id: &str) -> bool { - self.inner.get(block_id).is_some() - } - - pub(crate) fn get(&self, block_id: &str) -> Option> { - if !self.contains(block_id) { - return None; - } - let opened_doc = self.inner.get(block_id).unwrap(); - Some(opened_doc.clone()) + pub(crate) fn get(&self, block_id: &str) -> Option> { + Some(self.inner.get(block_id)?.clone()) } pub(crate) fn remove(&self, block_id: &str) { @@ -214,7 +205,7 @@ impl BlockEditors { } #[tracing::instrument(level = "trace", skip(web_socket, handlers))] -fn listen_ws_state_changed(web_socket: Arc, handlers: Arc) { +fn listen_ws_state_changed(web_socket: Arc, handlers: Arc) { tokio::spawn(async move { let mut notify = web_socket.subscribe_state_changed().await; while let Ok(state) = notify.recv().await { diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 96e4e50f17..aaaca7dbb4 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -1,5 +1,5 @@ use crate::web_socket::EditorCommandReceiver; -use crate::BlockUser; +use crate::TextBlockUser; use async_stream::stream; use flowy_collaboration::util::make_delta_from_revisions; use flowy_collaboration::{ @@ -21,14 +21,14 @@ use tokio::sync::{oneshot, RwLock}; // serial. pub(crate) struct EditBlockQueue { document: Arc>, - user: Arc, + user: Arc, rev_manager: Arc, receiver: Option, } impl EditBlockQueue { pub(crate) fn new( - user: Arc, + user: Arc, rev_manager: Arc, delta: RichTextDelta, receiver: EditorCommandReceiver, diff --git a/frontend/rust-lib/flowy-block/src/web_socket.rs b/frontend/rust-lib/flowy-block/src/web_socket.rs index 27ec604129..c6033286af 100644 --- a/frontend/rust-lib/flowy-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-block/src/web_socket.rs @@ -31,11 +31,11 @@ pub(crate) async fn make_block_ws_manager( rev_web_socket: Arc, ) -> Arc { let ws_data_provider = Arc::new(WSDataProvider::new(&doc_id, Arc::new(rev_manager.clone()))); - let resolver = Arc::new(BlockConflictResolver { edit_cmd_tx }); + let resolver = Arc::new(TextBlockConflictResolver { edit_cmd_tx }); let conflict_controller = RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); - let ws_data_stream = Arc::new(BlockRevisionWSDataStream::new(conflict_controller)); - let ws_data_sink = Arc::new(BlockWSDataSink(ws_data_provider)); + let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller)); + let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider)); let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); let ws_manager = Arc::new(RevisionWebSocketManager::new( "Block", @@ -62,11 +62,11 @@ fn listen_document_ws_state(_user_id: &str, _doc_id: &str, mut subscriber: broad }); } -pub(crate) struct BlockRevisionWSDataStream { +pub(crate) struct TextBlockRevisionWSDataStream { conflict_controller: Arc, } -impl BlockRevisionWSDataStream { +impl TextBlockRevisionWSDataStream { pub fn new(conflict_controller: RichTextConflictController) -> Self { Self { conflict_controller: Arc::new(conflict_controller), @@ -74,7 +74,7 @@ impl BlockRevisionWSDataStream { } } -impl RevisionWSDataStream for BlockRevisionWSDataStream { +impl RevisionWSDataStream for TextBlockRevisionWSDataStream { fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError> { let resolver = self.conflict_controller.clone(); Box::pin(async move { resolver.receive_bytes(bytes).await }) @@ -96,19 +96,19 @@ impl RevisionWSDataStream for BlockRevisionWSDataStream { } } -pub(crate) struct BlockWSDataSink(pub(crate) Arc); -impl RevisionWebSocketSink for BlockWSDataSink { +pub(crate) struct TextBlockWSDataSink(pub(crate) Arc); +impl RevisionWebSocketSink for TextBlockWSDataSink { fn next(&self) -> FutureResult, FlowyError> { let sink_provider = self.0.clone(); FutureResult::new(async move { sink_provider.next().await }) } } -struct BlockConflictResolver { +struct TextBlockConflictResolver { edit_cmd_tx: EditorCommandSender, } -impl ConflictResolver for BlockConflictResolver { +impl ConflictResolver for TextBlockConflictResolver { fn compose_delta(&self, delta: RichTextDelta) -> BoxResultFuture { let tx = self.edit_cmd_tx.clone(); Box::pin(async move { diff --git a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs index 0109302e96..a06eb24a44 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs @@ -1,4 +1,4 @@ -use flowy_block::block_editor::ClientBlockEditor; +use flowy_block::editor::ClientTextBlockEditor; use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; use flowy_collaboration::entities::revision::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; @@ -19,7 +19,7 @@ pub enum EditorScript { pub struct EditorTest { pub sdk: FlowySDKTest, - pub editor: Arc, + pub editor: Arc, } impl EditorTest { @@ -27,7 +27,7 @@ impl EditorTest { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; let test = ViewTest::new(&sdk).await; - let editor = sdk.block_manager.open_block(&test.view.id).await.unwrap(); + let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql index 96473ec177..1447085d7f 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql @@ -1,2 +1,3 @@ -- This file should undo anything in `up.sql` -DROP TABLE kv_table; \ No newline at end of file +DROP TABLE kv_table; +DROP TABLE grid_rev_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql index edde5d7dfa..c8b592109b 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql @@ -2,4 +2,13 @@ CREATE TABLE kv_table ( key TEXT NOT NULL PRIMARY KEY, value BLOB NOT NULL DEFAULT (x'') +); + +CREATE TABLE grid_rev_table ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + object_id TEXT NOT NULL DEFAULT '', + base_rev_id BIGINT NOT NULL DEFAULT 0, + rev_id BIGINT NOT NULL DEFAULT 0, + data BLOB NOT NULL DEFAULT (x''), + state INTEGER NOT NULL DEFAULT 0 ); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index f09fad218d..4722aaad5d 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -14,8 +14,8 @@ use crate::{ }; use bytes::Bytes; use flowy_collaboration::entities::{ - document_info::BlockId, revision::{RepeatedRevision, Revision}, + text_block_info::TextBlockId, }; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::ViewDataType; @@ -147,7 +147,7 @@ impl ViewController { } #[tracing::instrument(level = "debug", skip(self,params), fields(doc_id = %params.value), err)] - pub(crate) async fn delete_view(&self, params: BlockId) -> Result<(), FlowyError> { + pub(crate) async fn delete_view(&self, params: TextBlockId) -> Result<(), FlowyError> { if let Some(view_id) = KV::get_str(LATEST_VIEW_ID) { if view_id == params.value { let _ = KV::remove(LATEST_VIEW_ID); diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs index f0e1107535..393c0f5699 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs @@ -1,4 +1,4 @@ -use flowy_collaboration::entities::document_info::BlockInfo; +use flowy_collaboration::entities::text_block_info::TextBlockInfo; use flowy_folder::event_map::FolderEvent::*; use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; use flowy_folder_data_model::entities::workspace::WorkspaceId; @@ -161,14 +161,14 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { .await; } -pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> BlockInfo { +pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { let view_id: ViewId = view_id.into(); FolderEventBuilder::new(sdk.clone()) .event(SetLatestView) .payload(view_id) .async_send() .await - .parse::() + .parse::() } pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index bc3418f441..e4298b54e7 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -1,5 +1,5 @@ use crate::helper::*; -use flowy_collaboration::entities::{document_info::BlockInfo, revision::RevisionState}; +use flowy_collaboration::entities::{revision::RevisionState, text_block_info::TextBlockInfo}; use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; use flowy_folder_data_model::entities::{ app::{App, RepeatedApp}, @@ -58,7 +58,7 @@ pub struct FolderTest { pub app: App, pub view: View, pub trash: Vec, - pub document_info: Option, + pub document_info: Option, // pub folder_editor: } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs index bfc2fc1568..e74ad692d3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -44,7 +44,7 @@ impl GridBuilder { let grid_meta = GridMeta { grid_id: self.grid_id, fields: self.fields, - rows: self.rows, + blocks: vec![], }; // let _ = check_rows(&self.fields, &self.rows)?; diff --git a/frontend/rust-lib/flowy-net/src/http_server/document.rs b/frontend/rust-lib/flowy-net/src/http_server/document.rs index da33e1b8a0..1016e903e4 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -3,7 +3,9 @@ use crate::{ request::{HttpRequestBuilder, ResponseMiddleware}, }; use flowy_block::BlockCloudService; -use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; +use flowy_collaboration::entities::text_block_info::{ + CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo, +}; use flowy_error::FlowyError; use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; @@ -21,26 +23,26 @@ impl BlockHttpCloudService { } impl BlockCloudService for BlockHttpCloudService { - fn create_block(&self, token: &str, params: CreateBlockParams) -> FutureResult<(), FlowyError> { + fn create_block(&self, token: &str, params: CreateTextBlockParams) -> FutureResult<(), FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { create_document_request(&token, params, &url).await }) } - fn read_block(&self, token: &str, params: BlockId) -> FutureResult, FlowyError> { + fn read_block(&self, token: &str, params: TextBlockId) -> FutureResult, FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { read_document_request(&token, params, &url).await }) } - fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError> { + fn update_block(&self, token: &str, params: ResetTextBlockParams) -> FutureResult<(), FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { reset_doc_request(&token, params, &url).await }) } } -pub async fn create_document_request(token: &str, params: CreateBlockParams, url: &str) -> Result<(), FlowyError> { +pub async fn create_document_request(token: &str, params: CreateTextBlockParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() .post(&url.to_owned()) .header(HEADER_TOKEN, token) @@ -50,7 +52,11 @@ pub async fn create_document_request(token: &str, params: CreateBlockParams, url Ok(()) } -pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> Result, FlowyError> { +pub async fn read_document_request( + token: &str, + params: TextBlockId, + url: &str, +) -> Result, FlowyError> { let doc = request_builder() .get(&url.to_owned()) .header(HEADER_TOKEN, token) @@ -61,7 +67,7 @@ pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> R Ok(doc) } -pub async fn reset_doc_request(token: &str, params: ResetBlockParams, url: &str) -> Result<(), FlowyError> { +pub async fn reset_doc_request(token: &str, params: ResetTextBlockParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() .patch(&url.to_owned()) .header(HEADER_TOKEN, token) diff --git a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs index db23fbf2ef..89e107e44f 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs @@ -1,5 +1,5 @@ use flowy_collaboration::{ - entities::{document_info::BlockInfo, folder_info::FolderInfo}, + entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo}, errors::CollaborateError, protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, server_document::*, @@ -111,7 +111,7 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence { } impl DocumentCloudPersistence for LocalDocumentCloudPersistence { - fn read_document(&self, doc_id: &str) -> BoxResultFuture { + fn read_document(&self, doc_id: &str) -> BoxResultFuture { let storage = self.storage.clone(); let doc_id = doc_id.to_owned(); Box::pin(async move { @@ -127,7 +127,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture, CollaborateError> { + ) -> BoxResultFuture, CollaborateError> { let doc_id = doc_id.to_owned(); let storage = self.storage.clone(); Box::pin(async move { diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index 3bfa30e06a..b25bf9429f 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -4,7 +4,7 @@ use bytes::Bytes; use flowy_collaboration::{ client_document::default::initial_quill_delta_string, entities::{ - document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}, + text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}, ws_data::{ClientRevisionWSData, ClientRevisionWSDataType}, }, errors::CollaborateError, @@ -413,12 +413,12 @@ impl UserCloudService for LocalServer { } impl BlockCloudService for LocalServer { - fn create_block(&self, _token: &str, _params: CreateBlockParams) -> FutureResult<(), FlowyError> { + fn create_block(&self, _token: &str, _params: CreateTextBlockParams) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } - fn read_block(&self, _token: &str, params: BlockId) -> FutureResult, FlowyError> { - let doc = BlockInfo { + fn read_block(&self, _token: &str, params: TextBlockId) -> FutureResult, FlowyError> { + let doc = TextBlockInfo { block_id: params.value, text: initial_quill_delta_string(), rev_id: 0, @@ -427,7 +427,7 @@ impl BlockCloudService for LocalServer { FutureResult::new(async { Ok(Some(doc)) }) } - fn update_block(&self, _token: &str, _params: ResetBlockParams) -> FutureResult<(), FlowyError> { + fn update_block(&self, _token: &str, _params: ResetTextBlockParams) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } } diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index e648bd9e66..5550395229 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,5 +1,5 @@ use bytes::Bytes; -use flowy_block::BlockManager; +use flowy_block::TextBlockManager; use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; @@ -32,7 +32,7 @@ impl FolderDepsResolver { user_session: Arc, server_config: &ClientServerConfiguration, ws_conn: &Arc, - block_manager: &Arc, + text_block_manager: &Arc, grid_manager: &Arc, ) -> Arc { let user: Arc = Arc::new(WorkspaceUserImpl(user_session.clone())); @@ -43,7 +43,7 @@ impl FolderDepsResolver { Some(local_server) => local_server, }; - let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone()); + let view_data_processor = make_view_data_processor(text_block_manager.clone(), grid_manager.clone()); let folder_manager = Arc::new(FolderManager::new(user.clone(), cloud_service, database, view_data_processor, web_socket).await); @@ -60,10 +60,13 @@ impl FolderDepsResolver { } } -fn make_view_data_processor(block_manager: Arc, grid_manager: Arc) -> ViewDataProcessorMap { +fn make_view_data_processor( + text_block_manager: Arc, + grid_manager: Arc, +) -> ViewDataProcessorMap { let mut map: HashMap> = HashMap::new(); - let block_data_impl = BlockManagerViewDataImpl(block_manager); + let block_data_impl = BlockManagerViewDataImpl(text_block_manager); map.insert(block_data_impl.data_type(), Arc::new(block_data_impl)); let grid_data_impl = GridManagerViewDataImpl(grid_manager); @@ -130,45 +133,45 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl { } } -struct BlockManagerViewDataImpl(Arc); +struct BlockManagerViewDataImpl(Arc); impl ViewDataProcessor for BlockManagerViewDataImpl { fn initialize(&self) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); - FutureResult::new(async move { block_manager.init() }) + let manager = self.0.clone(); + FutureResult::new(async move { manager.init() }) } fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); + let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - let _ = block_manager.create_block(view_id, repeated_revision).await?; + let _ = manager.create_block(view_id, repeated_revision).await?; Ok(()) }) } fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); + let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - let _ = block_manager.delete_block(view_id)?; + let _ = manager.delete_block(view_id)?; Ok(()) }) } fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); + let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - let _ = block_manager.close_block(view_id)?; + let _ = manager.close_block(view_id)?; Ok(()) }) } fn delta_str(&self, view_id: &str) -> FutureResult { let view_id = view_id.to_string(); - let block_manager = self.0.clone(); + let manager = self.0.clone(); FutureResult::new(async move { - let editor = block_manager.open_block(view_id).await?; + let editor = manager.open_block(view_id).await?; let delta_str = editor.delta_str().await?; Ok(delta_str) }) diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs index c0a84d8d94..cac82f9c56 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs @@ -1,10 +1,10 @@ -mod block_deps; mod folder_deps; mod grid_deps; +mod text_block_deps; mod user_deps; mod util; -pub use block_deps::*; pub use folder_deps::*; pub use grid_deps::*; +pub use text_block_deps::*; pub use user_deps::*; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs similarity index 85% rename from frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs rename to frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs index f8c97d133c..5482bbe546 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs @@ -1,7 +1,7 @@ use bytes::Bytes; use flowy_block::{ errors::{internal_error, FlowyError}, - BlockCloudService, BlockManager, BlockUser, + BlockCloudService, TextBlockManager, TextBlockUser, }; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; @@ -16,22 +16,22 @@ use lib_infra::future::BoxResultFuture; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use std::{convert::TryInto, path::Path, sync::Arc}; -pub struct BlockDepsResolver(); -impl BlockDepsResolver { +pub struct TextBlockDepsResolver(); +impl TextBlockDepsResolver { pub fn resolve( local_server: Option>, ws_conn: Arc, user_session: Arc, server_config: &ClientServerConfiguration, - ) -> Arc { + ) -> Arc { let user = Arc::new(BlockUserImpl(user_session)); - let rev_web_socket = Arc::new(BlockWebSocket(ws_conn.clone())); + let rev_web_socket = Arc::new(TextBlockWebSocket(ws_conn.clone())); let cloud_service: Arc = match local_server { None => Arc::new(BlockHttpCloudService::new(server_config.clone())), Some(local_server) => local_server, }; - let manager = Arc::new(BlockManager::new(cloud_service, user, rev_web_socket)); + let manager = Arc::new(TextBlockManager::new(cloud_service, user, rev_web_socket)); let receiver = Arc::new(DocumentWSMessageReceiverImpl(manager.clone())); ws_conn.add_ws_message_receiver(receiver).unwrap(); @@ -40,7 +40,7 @@ impl BlockDepsResolver { } struct BlockUserImpl(Arc); -impl BlockUser for BlockUserImpl { +impl TextBlockUser for BlockUserImpl { fn user_dir(&self) -> Result { let dir = self.0.user_dir().map_err(|e| FlowyError::unauthorized().context(e))?; @@ -64,8 +64,8 @@ impl BlockUser for BlockUserImpl { } } -struct BlockWebSocket(Arc); -impl RevisionWebSocket for BlockWebSocket { +struct TextBlockWebSocket(Arc); +impl RevisionWebSocket for TextBlockWebSocket { fn send(&self, data: ClientRevisionWSData) -> BoxResultFuture<(), FlowyError> { let bytes: Bytes = data.try_into().unwrap(); let msg = WebSocketRawMessage { @@ -90,7 +90,7 @@ impl RevisionWebSocket for BlockWebSocket { } } -struct DocumentWSMessageReceiverImpl(Arc); +struct DocumentWSMessageReceiverImpl(Arc); impl WSMessageReceiver for DocumentWSMessageReceiverImpl { fn source(&self) -> WSChannel { WSChannel::Document diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 7c254acd66..7acf14952e 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -3,7 +3,7 @@ pub mod module; pub use flowy_net::get_client_server_configuration; use crate::deps_resolve::*; -use flowy_block::BlockManager; +use flowy_block::TextBlockManager; use flowy_folder::{errors::FlowyError, manager::FolderManager}; use flowy_grid::manager::GridManager; use flowy_net::ClientServerConfiguration; @@ -88,7 +88,7 @@ pub struct FlowySDK { #[allow(dead_code)] config: FlowySDKConfig, pub user_session: Arc, - pub block_manager: Arc, + pub text_block_manager: Arc, pub folder_manager: Arc, pub grid_manager: Arc, pub dispatcher: Arc, @@ -103,9 +103,9 @@ impl FlowySDK { tracing::debug!("🔥 {:?}", config); let runtime = tokio_default_runtime().unwrap(); let (local_server, ws_conn) = mk_local_server(&config.server_config); - let (user_session, block_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { + let (user_session, text_block_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { let user_session = mk_user_session(&config, &local_server, &config.server_config); - let block_manager = BlockDepsResolver::resolve( + let text_block_manager = TextBlockDepsResolver::resolve( local_server.clone(), ws_conn.clone(), user_session.clone(), @@ -119,7 +119,7 @@ impl FlowySDK { user_session.clone(), &config.server_config, &ws_conn, - &block_manager, + &text_block_manager, &grid_manager, ) .await; @@ -128,11 +128,23 @@ impl FlowySDK { local_server.run(); } ws_conn.init().await; - (user_session, block_manager, folder_manager, local_server, grid_manager) + ( + user_session, + text_block_manager, + folder_manager, + local_server, + grid_manager, + ) }); let dispatcher = Arc::new(EventDispatcher::construct(runtime, || { - mk_modules(&ws_conn, &folder_manager, &grid_manager, &user_session, &block_manager) + mk_modules( + &ws_conn, + &folder_manager, + &grid_manager, + &user_session, + &text_block_manager, + ) })); _start_listening(&dispatcher, &ws_conn, &user_session, &folder_manager); @@ -140,7 +152,7 @@ impl FlowySDK { Self { config, user_session, - block_manager, + text_block_manager, folder_manager, grid_manager, dispatcher, diff --git a/frontend/rust-lib/flowy-sdk/src/module.rs b/frontend/rust-lib/flowy-sdk/src/module.rs index 18bf44a2af..0a3fb1f87a 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -1,4 +1,4 @@ -use flowy_block::BlockManager; +use flowy_block::TextBlockManager; use flowy_folder::manager::FolderManager; use flowy_grid::manager::GridManager; use flowy_net::ws::connection::FlowyWebSocketConnect; @@ -11,14 +11,20 @@ pub fn mk_modules( folder_manager: &Arc, grid_manager: &Arc, user_session: &Arc, - block_manager: &Arc, + text_block_manager: &Arc, ) -> Vec { let user_module = mk_user_module(user_session.clone()); let folder_module = mk_folder_module(folder_manager.clone()); let network_module = mk_network_module(ws_conn.clone()); let grid_module = mk_grid_module(grid_manager.clone()); - let block_module = mk_block_module(block_manager.clone()); - vec![user_module, folder_module, network_module, grid_module, block_module] + let text_block_module = mk_text_block_module(text_block_manager.clone()); + vec![ + user_module, + folder_module, + network_module, + grid_module, + text_block_module, + ] } fn mk_user_module(user_session: Arc) -> Module { @@ -37,6 +43,6 @@ fn mk_grid_module(grid_manager: Arc) -> Module { flowy_grid::event_map::create(grid_manager) } -fn mk_block_module(block_manager: Arc) -> Module { - flowy_block::event_map::create(block_manager) +fn mk_text_block_module(text_block_manager: Arc) -> Module { + flowy_block::event_map::create(text_block_manager) } diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index 7bcbc30fdd..6c3ee45f37 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -1,9 +1,14 @@ -mod sql_impl; +mod folder_rev_impl; +mod grid_rev_impl; +mod text_block_rev_impl; + +pub use folder_rev_impl::*; +pub use grid_rev_impl::*; +pub use text_block_rev_impl::*; + use crate::RevisionRecord; use diesel::SqliteConnection; use flowy_collaboration::entities::revision::RevisionRange; -pub use sql_impl::*; - use flowy_error::FlowyResult; use std::fmt::Debug; diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs similarity index 98% rename from frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs rename to frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs index e985a98bd8..d7b56034c3 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs @@ -14,12 +14,12 @@ use flowy_database::{ use flowy_error::{internal_error, FlowyError, FlowyResult}; use std::sync::Arc; -pub struct SQLitePersistence { +pub struct SQLiteTextBlockRevisionPersistence { user_id: String, pub(crate) pool: Arc, } -impl RevisionDiskCache for SQLitePersistence { +impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { type Error = FlowyError; fn create_revision_records( @@ -83,7 +83,7 @@ impl RevisionDiskCache for SQLitePersistence { } } -impl SQLitePersistence { +impl SQLiteTextBlockRevisionPersistence { pub(crate) fn new(user_id: &str, pool: Arc) -> Self { Self { user_id: user_id.to_owned(), diff --git a/frontend/rust-lib/flowy-sync/src/cache/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/mod.rs index a6b5be4102..9ef6fb7da0 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/mod.rs @@ -1,325 +1,2 @@ -mod disk; -mod memory; - -use crate::cache::{ - disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLitePersistence}, - memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, -}; - -use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState}; -use flowy_database::ConnectionPool; -use flowy_error::{internal_error, FlowyError, FlowyResult}; - -use crate::RevisionCompact; -use std::collections::VecDeque; -use std::{borrow::Cow, sync::Arc}; -use tokio::sync::RwLock; -use tokio::task::spawn_blocking; - -pub const REVISION_WRITE_INTERVAL_IN_MILLIS: u64 = 600; - -pub struct RevisionPersistence { - user_id: String, - object_id: String, - disk_cache: Arc>, - memory_cache: Arc, - sync_seq: RwLock, -} -impl RevisionPersistence { - pub fn new(user_id: &str, object_id: &str, pool: Arc) -> RevisionPersistence { - let disk_cache = Arc::new(SQLitePersistence::new(user_id, pool)); - let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone()))); - let object_id = object_id.to_owned(); - let user_id = user_id.to_owned(); - let sync_seq = RwLock::new(RevisionSyncSequence::new()); - Self { - user_id, - object_id, - disk_cache, - memory_cache, - sync_seq, - } - } - - /// Save the revision that comes from remote to disk. - #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)] - pub(crate) async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> { - tracing::Span::current().record("rev_id", &revision.rev_id); - self.add(revision.clone(), RevisionState::Ack, true).await - } - - /// Append the revision that already existed in the local DB state to sync sequence - #[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)] - pub(crate) async fn sync_revision(&self, revision: &Revision) -> FlowyResult<()> { - tracing::Span::current().record("rev_id", &revision.rev_id); - self.add(revision.clone(), RevisionState::Sync, false).await?; - self.sync_seq.write().await.add(revision.rev_id)?; - Ok(()) - } - - /// Save the revision to disk and append it to the end of the sync sequence. - #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)] - pub(crate) async fn add_sync_revision(&self, revision: &Revision) -> FlowyResult - where - C: RevisionCompact, - { - let result = self.sync_seq.read().await.compact(); - match result { - None => { - tracing::Span::current().record("rev_id", &revision.rev_id); - self.add(revision.clone(), RevisionState::Sync, true).await?; - self.sync_seq.write().await.add(revision.rev_id)?; - Ok(revision.rev_id) - } - Some((range, mut compact_seq)) => { - tracing::Span::current().record("compact_range", &format!("{}", range).as_str()); - let mut revisions = self.revisions_in_range(&range).await?; - if range.to_rev_ids().len() != revisions.len() { - debug_assert_eq!(range.to_rev_ids().len(), revisions.len()); - } - - // append the new revision - revisions.push(revision.clone()); - - // compact multiple revisions into one - let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?; - let rev_id = compact_revision.rev_id; - tracing::Span::current().record("rev_id", &rev_id); - - // insert new revision - compact_seq.push_back(rev_id); - - // replace the revisions in range with compact revision - self.compact(&range, compact_revision).await?; - debug_assert_eq!(self.sync_seq.read().await.len(), compact_seq.len()); - self.sync_seq.write().await.reset(compact_seq); - Ok(rev_id) - } - } - } - - /// Remove the revision with rev_id from the sync sequence. - pub(crate) async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> { - if self.sync_seq.write().await.ack(&rev_id).is_ok() { - self.memory_cache.ack(&rev_id).await; - } - Ok(()) - } - - pub(crate) async fn next_sync_revision(&self) -> FlowyResult> { - match self.sync_seq.read().await.next_rev_id() { - None => Ok(None), - Some(rev_id) => Ok(self.get(rev_id).await.map(|record| record.revision)), - } - } - - /// The cache gets reset while it conflicts with the remote revisions. - #[tracing::instrument(level = "trace", skip(self, revisions), err)] - pub(crate) async fn reset(&self, revisions: Vec) -> FlowyResult<()> { - let records = revisions - .to_vec() - .into_iter() - .map(|revision| RevisionRecord { - revision, - state: RevisionState::Sync, - write_to_disk: false, - }) - .collect::>(); - - let _ = self - .disk_cache - .delete_and_insert_records(&self.object_id, None, records.clone())?; - let _ = self.memory_cache.reset_with_revisions(records).await; - self.sync_seq.write().await.clear(); - Ok(()) - } - - async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> { - if self.memory_cache.contains(&revision.rev_id) { - tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state); - return Ok(()); - } - let record = RevisionRecord { - revision, - state, - write_to_disk, - }; - - self.memory_cache.add(Cow::Owned(record)).await; - Ok(()) - } - - async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> { - self.memory_cache.remove_with_range(range); - let rev_ids = range.to_rev_ids(); - let _ = self - .disk_cache - .delete_revision_records(&self.object_id, Some(rev_ids))?; - - self.add(new_revision, RevisionState::Sync, true).await?; - Ok(()) - } - - pub async fn get(&self, rev_id: i64) -> Option { - match self.memory_cache.get(&rev_id).await { - None => match self - .disk_cache - .read_revision_records(&self.object_id, Some(vec![rev_id])) - { - Ok(mut records) => { - let record = records.pop()?; - assert!(records.is_empty()); - Some(record) - } - Err(e) => { - tracing::error!("{}", e); - None - } - }, - Some(revision) => Some(revision), - } - } - - pub fn batch_get(&self, doc_id: &str) -> FlowyResult> { - self.disk_cache.read_revision_records(doc_id, None) - } - - // Read the revision which rev_id >= range.start && rev_id <= range.end - pub async fn revisions_in_range(&self, range: &RevisionRange) -> FlowyResult> { - let range = range.clone(); - let mut records = self.memory_cache.get_with_range(&range).await?; - let range_len = range.len() as usize; - if records.len() != range_len { - let disk_cache = self.disk_cache.clone(); - let object_id = self.object_id.clone(); - records = spawn_blocking(move || disk_cache.read_revision_records_with_range(&object_id, &range)) - .await - .map_err(internal_error)??; - - if records.len() != range_len { - // #[cfg(debug_assertions)] - // records.iter().for_each(|record| { - // let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap(); - // tracing::trace!("{}", delta.to_string()); - // }); - tracing::error!("Expect revision len {},but receive {}", range_len, records.len()); - } - } - Ok(records - .into_iter() - .map(|record| record.revision) - .collect::>()) - } -} - -pub fn mk_revision_disk_cache( - user_id: &str, - pool: Arc, -) -> Arc> { - Arc::new(SQLitePersistence::new(user_id, pool)) -} - -impl RevisionMemoryCacheDelegate for Arc { - #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)] - fn checkpoint_tick(&self, mut records: Vec) -> FlowyResult<()> { - let conn = &*self.pool.get().map_err(internal_error)?; - records.retain(|record| record.write_to_disk); - if !records.is_empty() { - tracing::Span::current().record( - "checkpoint_result", - &format!("{} records were saved", records.len()).as_str(), - ); - let _ = self.create_revision_records(records, conn)?; - } - Ok(()) - } - - fn receive_ack(&self, object_id: &str, rev_id: i64) { - let changeset = RevisionChangeset { - object_id: object_id.to_string(), - rev_id: rev_id.into(), - state: RevisionTableState::Ack, - }; - match self.update_revision_record(vec![changeset]) { - Ok(_) => {} - Err(e) => tracing::error!("{}", e), - } - } -} - -#[derive(Clone, Debug)] -pub struct RevisionRecord { - pub revision: Revision, - pub state: RevisionState, - pub write_to_disk: bool, -} - -impl RevisionRecord { - pub fn ack(&mut self) { - self.state = RevisionState::Ack; - } -} - -#[derive(Default)] -struct RevisionSyncSequence(VecDeque); -impl RevisionSyncSequence { - fn new() -> Self { - RevisionSyncSequence::default() - } - - fn add(&mut self, new_rev_id: i64) -> FlowyResult<()> { - // The last revision's rev_id must be greater than the new one. - if let Some(rev_id) = self.0.back() { - if *rev_id >= new_rev_id { - return Err( - FlowyError::internal().context(format!("The new revision's id must be greater than {}", rev_id)) - ); - } - } - self.0.push_back(new_rev_id); - Ok(()) - } - - fn ack(&mut self, rev_id: &i64) -> FlowyResult<()> { - let cur_rev_id = self.0.front().cloned(); - if let Some(pop_rev_id) = cur_rev_id { - if &pop_rev_id != rev_id { - let desc = format!( - "The ack rev_id:{} is not equal to the current rev_id:{}", - rev_id, pop_rev_id - ); - return Err(FlowyError::internal().context(desc)); - } - let _ = self.0.pop_front(); - } - Ok(()) - } - - fn next_rev_id(&self) -> Option { - self.0.front().cloned() - } - - fn reset(&mut self, new_seq: VecDeque) { - self.0 = new_seq; - } - - fn clear(&mut self) { - self.0.clear(); - } - - fn len(&self) -> usize { - self.0.len() - } - - // Compact the rev_ids into one except the current synchronizing rev_id. - fn compact(&self) -> Option<(RevisionRange, VecDeque)> { - self.next_rev_id()?; - - let mut new_seq = self.0.clone(); - let mut drained = new_seq.drain(1..).collect::>(); - - let start = drained.pop_front()?; - let end = drained.pop_back().unwrap_or(start); - Some((RevisionRange { start, end }, new_seq)) - } -} +pub(crate) mod disk; +pub(crate) mod memory; diff --git a/frontend/rust-lib/flowy-sync/src/lib.rs b/frontend/rust-lib/flowy-sync/src/lib.rs index 16cc05d2c7..05e60c00e0 100644 --- a/frontend/rust-lib/flowy-sync/src/lib.rs +++ b/frontend/rust-lib/flowy-sync/src/lib.rs @@ -1,11 +1,13 @@ mod cache; mod conflict_resolve; mod rev_manager; +mod rev_persistence; mod ws_manager; pub use cache::*; pub use conflict_resolve::*; pub use rev_manager::*; +pub use rev_persistence::*; pub use ws_manager::*; #[macro_use] diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs new file mode 100644 index 0000000000..428e708916 --- /dev/null +++ b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs @@ -0,0 +1,322 @@ +use crate::cache::{ + disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLiteTextBlockRevisionPersistence}, + memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, +}; + +use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState}; +use flowy_database::ConnectionPool; +use flowy_error::{internal_error, FlowyError, FlowyResult}; + +use crate::RevisionCompact; +use std::collections::VecDeque; +use std::{borrow::Cow, sync::Arc}; +use tokio::sync::RwLock; +use tokio::task::spawn_blocking; + +pub const REVISION_WRITE_INTERVAL_IN_MILLIS: u64 = 600; + +pub struct RevisionPersistence { + user_id: String, + object_id: String, + disk_cache: Arc>, + memory_cache: Arc, + sync_seq: RwLock, +} +impl RevisionPersistence { + pub fn new(user_id: &str, object_id: &str, pool: Arc) -> RevisionPersistence { + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); + let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone()))); + let object_id = object_id.to_owned(); + let user_id = user_id.to_owned(); + let sync_seq = RwLock::new(RevisionSyncSequence::new()); + Self { + user_id, + object_id, + disk_cache, + memory_cache, + sync_seq, + } + } + + /// Save the revision that comes from remote to disk. + #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)] + pub(crate) async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> { + tracing::Span::current().record("rev_id", &revision.rev_id); + self.add(revision.clone(), RevisionState::Ack, true).await + } + + /// Append the revision that already existed in the local DB state to sync sequence + #[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)] + pub(crate) async fn sync_revision(&self, revision: &Revision) -> FlowyResult<()> { + tracing::Span::current().record("rev_id", &revision.rev_id); + self.add(revision.clone(), RevisionState::Sync, false).await?; + self.sync_seq.write().await.add(revision.rev_id)?; + Ok(()) + } + + /// Save the revision to disk and append it to the end of the sync sequence. + #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)] + pub(crate) async fn add_sync_revision(&self, revision: &Revision) -> FlowyResult + where + C: RevisionCompact, + { + let result = self.sync_seq.read().await.compact(); + match result { + None => { + tracing::Span::current().record("rev_id", &revision.rev_id); + self.add(revision.clone(), RevisionState::Sync, true).await?; + self.sync_seq.write().await.add(revision.rev_id)?; + Ok(revision.rev_id) + } + Some((range, mut compact_seq)) => { + tracing::Span::current().record("compact_range", &format!("{}", range).as_str()); + let mut revisions = self.revisions_in_range(&range).await?; + if range.to_rev_ids().len() != revisions.len() { + debug_assert_eq!(range.to_rev_ids().len(), revisions.len()); + } + + // append the new revision + revisions.push(revision.clone()); + + // compact multiple revisions into one + let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?; + let rev_id = compact_revision.rev_id; + tracing::Span::current().record("rev_id", &rev_id); + + // insert new revision + compact_seq.push_back(rev_id); + + // replace the revisions in range with compact revision + self.compact(&range, compact_revision).await?; + debug_assert_eq!(self.sync_seq.read().await.len(), compact_seq.len()); + self.sync_seq.write().await.reset(compact_seq); + Ok(rev_id) + } + } + } + + /// Remove the revision with rev_id from the sync sequence. + pub(crate) async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> { + if self.sync_seq.write().await.ack(&rev_id).is_ok() { + self.memory_cache.ack(&rev_id).await; + } + Ok(()) + } + + pub(crate) async fn next_sync_revision(&self) -> FlowyResult> { + match self.sync_seq.read().await.next_rev_id() { + None => Ok(None), + Some(rev_id) => Ok(self.get(rev_id).await.map(|record| record.revision)), + } + } + + /// The cache gets reset while it conflicts with the remote revisions. + #[tracing::instrument(level = "trace", skip(self, revisions), err)] + pub(crate) async fn reset(&self, revisions: Vec) -> FlowyResult<()> { + let records = revisions + .to_vec() + .into_iter() + .map(|revision| RevisionRecord { + revision, + state: RevisionState::Sync, + write_to_disk: false, + }) + .collect::>(); + + let _ = self + .disk_cache + .delete_and_insert_records(&self.object_id, None, records.clone())?; + let _ = self.memory_cache.reset_with_revisions(records).await; + self.sync_seq.write().await.clear(); + Ok(()) + } + + async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> { + if self.memory_cache.contains(&revision.rev_id) { + tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state); + return Ok(()); + } + let record = RevisionRecord { + revision, + state, + write_to_disk, + }; + + self.memory_cache.add(Cow::Owned(record)).await; + Ok(()) + } + + async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> { + self.memory_cache.remove_with_range(range); + let rev_ids = range.to_rev_ids(); + let _ = self + .disk_cache + .delete_revision_records(&self.object_id, Some(rev_ids))?; + + self.add(new_revision, RevisionState::Sync, true).await?; + Ok(()) + } + + pub async fn get(&self, rev_id: i64) -> Option { + match self.memory_cache.get(&rev_id).await { + None => match self + .disk_cache + .read_revision_records(&self.object_id, Some(vec![rev_id])) + { + Ok(mut records) => { + let record = records.pop()?; + assert!(records.is_empty()); + Some(record) + } + Err(e) => { + tracing::error!("{}", e); + None + } + }, + Some(revision) => Some(revision), + } + } + + pub fn batch_get(&self, doc_id: &str) -> FlowyResult> { + self.disk_cache.read_revision_records(doc_id, None) + } + + // Read the revision which rev_id >= range.start && rev_id <= range.end + pub async fn revisions_in_range(&self, range: &RevisionRange) -> FlowyResult> { + let range = range.clone(); + let mut records = self.memory_cache.get_with_range(&range).await?; + let range_len = range.len() as usize; + if records.len() != range_len { + let disk_cache = self.disk_cache.clone(); + let object_id = self.object_id.clone(); + records = spawn_blocking(move || disk_cache.read_revision_records_with_range(&object_id, &range)) + .await + .map_err(internal_error)??; + + if records.len() != range_len { + // #[cfg(debug_assertions)] + // records.iter().for_each(|record| { + // let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap(); + // tracing::trace!("{}", delta.to_string()); + // }); + tracing::error!("Expect revision len {},but receive {}", range_len, records.len()); + } + } + Ok(records + .into_iter() + .map(|record| record.revision) + .collect::>()) + } +} + +pub fn mk_revision_disk_cache( + user_id: &str, + pool: Arc, +) -> Arc> { + Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)) +} + +impl RevisionMemoryCacheDelegate for Arc { + #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)] + fn checkpoint_tick(&self, mut records: Vec) -> FlowyResult<()> { + let conn = &*self.pool.get().map_err(internal_error)?; + records.retain(|record| record.write_to_disk); + if !records.is_empty() { + tracing::Span::current().record( + "checkpoint_result", + &format!("{} records were saved", records.len()).as_str(), + ); + let _ = self.create_revision_records(records, conn)?; + } + Ok(()) + } + + fn receive_ack(&self, object_id: &str, rev_id: i64) { + let changeset = RevisionChangeset { + object_id: object_id.to_string(), + rev_id: rev_id.into(), + state: RevisionTableState::Ack, + }; + match self.update_revision_record(vec![changeset]) { + Ok(_) => {} + Err(e) => tracing::error!("{}", e), + } + } +} + +#[derive(Clone, Debug)] +pub struct RevisionRecord { + pub revision: Revision, + pub state: RevisionState, + pub write_to_disk: bool, +} + +impl RevisionRecord { + pub fn ack(&mut self) { + self.state = RevisionState::Ack; + } +} + +#[derive(Default)] +struct RevisionSyncSequence(VecDeque); +impl RevisionSyncSequence { + fn new() -> Self { + RevisionSyncSequence::default() + } + + fn add(&mut self, new_rev_id: i64) -> FlowyResult<()> { + // The last revision's rev_id must be greater than the new one. + if let Some(rev_id) = self.0.back() { + if *rev_id >= new_rev_id { + return Err( + FlowyError::internal().context(format!("The new revision's id must be greater than {}", rev_id)) + ); + } + } + self.0.push_back(new_rev_id); + Ok(()) + } + + fn ack(&mut self, rev_id: &i64) -> FlowyResult<()> { + let cur_rev_id = self.0.front().cloned(); + if let Some(pop_rev_id) = cur_rev_id { + if &pop_rev_id != rev_id { + let desc = format!( + "The ack rev_id:{} is not equal to the current rev_id:{}", + rev_id, pop_rev_id + ); + return Err(FlowyError::internal().context(desc)); + } + let _ = self.0.pop_front(); + } + Ok(()) + } + + fn next_rev_id(&self) -> Option { + self.0.front().cloned() + } + + fn reset(&mut self, new_seq: VecDeque) { + self.0 = new_seq; + } + + fn clear(&mut self) { + self.0.clear(); + } + + fn len(&self) -> usize { + self.0.len() + } + + // Compact the rev_ids into one except the current synchronizing rev_id. + fn compact(&self) -> Option<(RevisionRange, VecDeque)> { + self.next_rev_id()?; + + let mut new_seq = self.0.clone(); + let mut drained = new_seq.drain(1..).collect::>(); + + let start = drained.pop_front()?; + let end = drained.pop_back().unwrap_or(start); + Some((RevisionRange { start, end }, new_seq)) + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs new file mode 100644 index 0000000000..23f07e3efb --- /dev/null +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -0,0 +1,115 @@ +use crate::entities::revision::{md5, RepeatedRevision, Revision}; +use crate::errors::{internal_error, CollaborateError, CollaborateResult}; +use crate::util::{cal_diff, make_delta_from_revisions}; +use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowOrder}; +use lib_infra::uuid; +use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use std::sync::Arc; + +pub type BlockMetaDelta = PlainTextDelta; +pub type BlockDeltaBuilder = PlainTextDeltaBuilder; + +pub struct BlockMetaPad { + pub(crate) block_meta: Arc, + pub(crate) delta: BlockMetaDelta, +} + +impl BlockMetaPad { + pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult { + let s = delta.to_str()?; + let block_delta: BlockMeta = serde_json::from_str(&s).map_err(|e| { + CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) + })?; + + Ok(Self { + block_meta: Arc::new(block_delta), + delta, + }) + } + + pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { + let block_delta: BlockMetaDelta = make_delta_from_revisions::(revisions)?; + Self::from_delta(block_delta) + } + + pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { + self.modify(|grid| { + grid.rows.push(row); + Ok(Some(())) + }) + } + + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + self.modify(|grid| { + grid.rows.retain(|row| !row_ids.contains(&row.id)); + Ok(Some(())) + }) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) + } + + pub fn delta_str(&self) -> String { + self.delta.to_delta_str() + } + + pub fn modify(&mut self, f: F) -> CollaborateResult> + where + F: FnOnce(&mut BlockMeta) -> CollaborateResult>, + { + let cloned_meta = self.block_meta.clone(); + match f(Arc::make_mut(&mut self.block_meta))? { + None => Ok(None), + Some(_) => { + let old = json_from_grid(&cloned_meta)?; + let new = json_from_grid(&self.block_meta)?; + match cal_diff::(old, new) { + None => Ok(None), + Some(delta) => { + self.delta = self.delta.compose(&delta)?; + Ok(Some(BlockMetaChange { delta, md5: self.md5() })) + } + } + } + } + } +} + +fn json_from_grid(block_meta: &Arc) -> CollaborateResult { + let json = serde_json::to_string(block_meta) + .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; + Ok(json) +} + +pub struct BlockMetaChange { + pub delta: BlockMetaDelta, + /// md5: the md5 of the grid after applying the change. + pub md5: String, +} + +pub fn make_block_meta_delta(block_meta: &BlockMeta) -> BlockMetaDelta { + let json = serde_json::to_string(&block_meta).unwrap(); + PlainTextDeltaBuilder::new().insert(&json).build() +} + +pub fn make_block_meta_revisions(user_id: &str, block_meta: &BlockMeta) -> RepeatedRevision { + let delta = make_block_meta_delta(block_meta); + let bytes = delta.to_bytes(); + let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); + revision.into() +} + +impl std::default::Default for BlockMetaPad { + fn default() -> Self { + let block_meta = BlockMeta { + block_id: uuid(), + rows: vec![], + }; + let delta = make_block_meta_delta(&block_meta); + BlockMetaPad { + block_meta: Arc::new(block_meta), + delta, + } + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 32b3f968b3..f61cd484fc 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -33,7 +33,7 @@ impl GridMetaPad { pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { self.modify_grid(|grid| { - grid.rows.push(row); + // grid.rows.push(row); Ok(Some(())) }) } @@ -47,7 +47,7 @@ impl GridMetaPad { pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify_grid(|grid| { - grid.rows.retain(|row| !row_ids.contains(&row.id)); + // grid.rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } @@ -74,17 +74,17 @@ impl GridMetaPad { .map(FieldOrder::from) .collect::>(); - let row_orders = self - .grid_meta - .rows - .iter() - .map(RowOrder::from) - .collect::>(); + // let row_orders = self + // .grid_meta + // .rows + // .iter() + // .map(RowOrder::from) + // .collect::>(); Grid { id: "".to_string(), field_orders, - row_orders, + row_orders: vec![], } } @@ -147,7 +147,7 @@ impl std::default::Default for GridMetaPad { let grid = GridMeta { grid_id: uuid(), fields: vec![], - rows: vec![], + blocks: vec![], }; let delta = make_grid_delta(&grid); GridMetaPad { diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index ee5a403a57..8ecb671968 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,3 +1,5 @@ +mod block_pad; mod grid_pad; +pub use block_pad::*; pub use grid_pad::*; diff --git a/shared-lib/flowy-collaboration/src/entities/mod.rs b/shared-lib/flowy-collaboration/src/entities/mod.rs index f31f9e34fd..8989125677 100644 --- a/shared-lib/flowy-collaboration/src/entities/mod.rs +++ b/shared-lib/flowy-collaboration/src/entities/mod.rs @@ -1,5 +1,5 @@ -pub mod document_info; pub mod folder_info; pub mod parser; pub mod revision; +pub mod text_block_info; pub mod ws_data; diff --git a/shared-lib/flowy-collaboration/src/entities/document_info.rs b/shared-lib/flowy-collaboration/src/entities/text_block_info.rs similarity index 78% rename from shared-lib/flowy-collaboration/src/entities/document_info.rs rename to shared-lib/flowy-collaboration/src/entities/text_block_info.rs index f80ab97207..c325fdad07 100644 --- a/shared-lib/flowy-collaboration/src/entities/document_info.rs +++ b/shared-lib/flowy-collaboration/src/entities/text_block_info.rs @@ -6,7 +6,7 @@ use flowy_derive::ProtoBuf; use lib_ot::{errors::OTError, rich_text::RichTextDelta}; #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct CreateBlockParams { +pub struct CreateTextBlockParams { #[pb(index = 1)] pub id: String, @@ -15,7 +15,7 @@ pub struct CreateBlockParams { } #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)] -pub struct BlockInfo { +pub struct TextBlockInfo { #[pb(index = 1)] pub block_id: String, @@ -29,14 +29,14 @@ pub struct BlockInfo { pub base_rev_id: i64, } -impl BlockInfo { +impl TextBlockInfo { pub fn delta(&self) -> Result { let delta = RichTextDelta::from_bytes(&self.text)?; Ok(delta) } } -impl std::convert::TryFrom for BlockInfo { +impl std::convert::TryFrom for TextBlockInfo { type Error = CollaborateError; fn try_from(revision: Revision) -> Result { @@ -48,7 +48,7 @@ impl std::convert::TryFrom for BlockInfo { let delta = RichTextDelta::from_bytes(&revision.delta_data)?; let doc_json = delta.to_delta_str(); - Ok(BlockInfo { + Ok(TextBlockInfo { block_id: revision.object_id, text: doc_json, rev_id: revision.rev_id, @@ -58,7 +58,7 @@ impl std::convert::TryFrom for BlockInfo { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct ResetBlockParams { +pub struct ResetTextBlockParams { #[pb(index = 1)] pub block_id: String, @@ -67,7 +67,7 @@ pub struct ResetBlockParams { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct BlockDelta { +pub struct TextBlockDelta { #[pb(index = 1)] pub block_id: String, @@ -88,30 +88,30 @@ pub struct NewDocUser { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct BlockId { +pub struct TextBlockId { #[pb(index = 1)] pub value: String, } -impl AsRef for BlockId { +impl AsRef for TextBlockId { fn as_ref(&self) -> &str { &self.value } } -impl std::convert::From for BlockId { +impl std::convert::From for TextBlockId { fn from(value: String) -> Self { - BlockId { value } + TextBlockId { value } } } -impl std::convert::From for String { - fn from(block_id: BlockId) -> Self { +impl std::convert::From for String { + fn from(block_id: TextBlockId) -> Self { block_id.value } } -impl std::convert::From<&String> for BlockId { +impl std::convert::From<&String> for TextBlockId { fn from(s: &String) -> Self { - BlockId { value: s.to_owned() } + TextBlockId { value: s.to_owned() } } } diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs b/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs index 137466e63f..d0627984e3 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs @@ -7,8 +7,8 @@ pub use folder_info::*; mod ws_data; pub use ws_data::*; +mod text_block_info; +pub use text_block_info::*; + mod revision; pub use revision::*; - -mod document_info; -pub use document_info::*; diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs b/shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs similarity index 85% rename from shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs rename to shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs index 28b3eb6bde..1e44767a92 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs @@ -17,14 +17,14 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `document_info.proto` +//! Generated file from `text_block_info.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct CreateBlockParams { +pub struct CreateTextBlockParams { // message fields pub id: ::std::string::String, pub revisions: ::protobuf::SingularPtrField, @@ -33,14 +33,14 @@ pub struct CreateBlockParams { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a CreateBlockParams { - fn default() -> &'a CreateBlockParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a CreateTextBlockParams { + fn default() -> &'a CreateTextBlockParams { + ::default_instance() } } -impl CreateBlockParams { - pub fn new() -> CreateBlockParams { +impl CreateTextBlockParams { + pub fn new() -> CreateTextBlockParams { ::std::default::Default::default() } @@ -104,7 +104,7 @@ impl CreateBlockParams { } } -impl ::protobuf::Message for CreateBlockParams { +impl ::protobuf::Message for CreateTextBlockParams { fn is_initialized(&self) -> bool { for v in &self.revisions { if !v.is_initialized() { @@ -187,8 +187,8 @@ impl ::protobuf::Message for CreateBlockParams { Self::descriptor_static() } - fn new() -> CreateBlockParams { - CreateBlockParams::new() + fn new() -> CreateTextBlockParams { + CreateTextBlockParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -197,29 +197,29 @@ impl ::protobuf::Message for CreateBlockParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &CreateBlockParams| { &m.id }, - |m: &mut CreateBlockParams| { &mut m.id }, + |m: &CreateTextBlockParams| { &m.id }, + |m: &mut CreateTextBlockParams| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "revisions", - |m: &CreateBlockParams| { &m.revisions }, - |m: &mut CreateBlockParams| { &mut m.revisions }, + |m: &CreateTextBlockParams| { &m.revisions }, + |m: &mut CreateTextBlockParams| { &mut m.revisions }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CreateBlockParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateTextBlockParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static CreateBlockParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CreateBlockParams::new) + fn default_instance() -> &'static CreateTextBlockParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateTextBlockParams::new) } } -impl ::protobuf::Clear for CreateBlockParams { +impl ::protobuf::Clear for CreateTextBlockParams { fn clear(&mut self) { self.id.clear(); self.revisions.clear(); @@ -227,20 +227,20 @@ impl ::protobuf::Clear for CreateBlockParams { } } -impl ::std::fmt::Debug for CreateBlockParams { +impl ::std::fmt::Debug for CreateTextBlockParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CreateBlockParams { +impl ::protobuf::reflect::ProtobufValue for CreateTextBlockParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct BlockInfo { +pub struct TextBlockInfo { // message fields pub block_id: ::std::string::String, pub text: ::std::string::String, @@ -251,14 +251,14 @@ pub struct BlockInfo { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockInfo { - fn default() -> &'a BlockInfo { - ::default_instance() +impl<'a> ::std::default::Default for &'a TextBlockInfo { + fn default() -> &'a TextBlockInfo { + ::default_instance() } } -impl BlockInfo { - pub fn new() -> BlockInfo { +impl TextBlockInfo { + pub fn new() -> TextBlockInfo { ::std::default::Default::default() } @@ -345,7 +345,7 @@ impl BlockInfo { } } -impl ::protobuf::Message for BlockInfo { +impl ::protobuf::Message for TextBlockInfo { fn is_initialized(&self) -> bool { true } @@ -446,8 +446,8 @@ impl ::protobuf::Message for BlockInfo { Self::descriptor_static() } - fn new() -> BlockInfo { - BlockInfo::new() + fn new() -> TextBlockInfo { + TextBlockInfo::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -456,39 +456,39 @@ impl ::protobuf::Message for BlockInfo { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &BlockInfo| { &m.block_id }, - |m: &mut BlockInfo| { &mut m.block_id }, + |m: &TextBlockInfo| { &m.block_id }, + |m: &mut TextBlockInfo| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "text", - |m: &BlockInfo| { &m.text }, - |m: &mut BlockInfo| { &mut m.text }, + |m: &TextBlockInfo| { &m.text }, + |m: &mut TextBlockInfo| { &mut m.text }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( "rev_id", - |m: &BlockInfo| { &m.rev_id }, - |m: &mut BlockInfo| { &mut m.rev_id }, + |m: &TextBlockInfo| { &m.rev_id }, + |m: &mut TextBlockInfo| { &mut m.rev_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( "base_rev_id", - |m: &BlockInfo| { &m.base_rev_id }, - |m: &mut BlockInfo| { &mut m.base_rev_id }, + |m: &TextBlockInfo| { &m.base_rev_id }, + |m: &mut TextBlockInfo| { &mut m.base_rev_id }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockInfo", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TextBlockInfo", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockInfo { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockInfo::new) + fn default_instance() -> &'static TextBlockInfo { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TextBlockInfo::new) } } -impl ::protobuf::Clear for BlockInfo { +impl ::protobuf::Clear for TextBlockInfo { fn clear(&mut self) { self.block_id.clear(); self.text.clear(); @@ -498,20 +498,20 @@ impl ::protobuf::Clear for BlockInfo { } } -impl ::std::fmt::Debug for BlockInfo { +impl ::std::fmt::Debug for TextBlockInfo { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockInfo { +impl ::protobuf::reflect::ProtobufValue for TextBlockInfo { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct ResetBlockParams { +pub struct ResetTextBlockParams { // message fields pub block_id: ::std::string::String, pub revisions: ::protobuf::SingularPtrField, @@ -520,14 +520,14 @@ pub struct ResetBlockParams { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a ResetBlockParams { - fn default() -> &'a ResetBlockParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a ResetTextBlockParams { + fn default() -> &'a ResetTextBlockParams { + ::default_instance() } } -impl ResetBlockParams { - pub fn new() -> ResetBlockParams { +impl ResetTextBlockParams { + pub fn new() -> ResetTextBlockParams { ::std::default::Default::default() } @@ -591,7 +591,7 @@ impl ResetBlockParams { } } -impl ::protobuf::Message for ResetBlockParams { +impl ::protobuf::Message for ResetTextBlockParams { fn is_initialized(&self) -> bool { for v in &self.revisions { if !v.is_initialized() { @@ -674,8 +674,8 @@ impl ::protobuf::Message for ResetBlockParams { Self::descriptor_static() } - fn new() -> ResetBlockParams { - ResetBlockParams::new() + fn new() -> ResetTextBlockParams { + ResetTextBlockParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -684,29 +684,29 @@ impl ::protobuf::Message for ResetBlockParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &ResetBlockParams| { &m.block_id }, - |m: &mut ResetBlockParams| { &mut m.block_id }, + |m: &ResetTextBlockParams| { &m.block_id }, + |m: &mut ResetTextBlockParams| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "revisions", - |m: &ResetBlockParams| { &m.revisions }, - |m: &mut ResetBlockParams| { &mut m.revisions }, + |m: &ResetTextBlockParams| { &m.revisions }, + |m: &mut ResetTextBlockParams| { &mut m.revisions }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "ResetBlockParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ResetTextBlockParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static ResetBlockParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(ResetBlockParams::new) + fn default_instance() -> &'static ResetTextBlockParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ResetTextBlockParams::new) } } -impl ::protobuf::Clear for ResetBlockParams { +impl ::protobuf::Clear for ResetTextBlockParams { fn clear(&mut self) { self.block_id.clear(); self.revisions.clear(); @@ -714,20 +714,20 @@ impl ::protobuf::Clear for ResetBlockParams { } } -impl ::std::fmt::Debug for ResetBlockParams { +impl ::std::fmt::Debug for ResetTextBlockParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for ResetBlockParams { +impl ::protobuf::reflect::ProtobufValue for ResetTextBlockParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct BlockDelta { +pub struct TextBlockDelta { // message fields pub block_id: ::std::string::String, pub delta_str: ::std::string::String, @@ -736,14 +736,14 @@ pub struct BlockDelta { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockDelta { - fn default() -> &'a BlockDelta { - ::default_instance() +impl<'a> ::std::default::Default for &'a TextBlockDelta { + fn default() -> &'a TextBlockDelta { + ::default_instance() } } -impl BlockDelta { - pub fn new() -> BlockDelta { +impl TextBlockDelta { + pub fn new() -> TextBlockDelta { ::std::default::Default::default() } @@ -800,7 +800,7 @@ impl BlockDelta { } } -impl ::protobuf::Message for BlockDelta { +impl ::protobuf::Message for TextBlockDelta { fn is_initialized(&self) -> bool { true } @@ -875,8 +875,8 @@ impl ::protobuf::Message for BlockDelta { Self::descriptor_static() } - fn new() -> BlockDelta { - BlockDelta::new() + fn new() -> TextBlockDelta { + TextBlockDelta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -885,29 +885,29 @@ impl ::protobuf::Message for BlockDelta { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &BlockDelta| { &m.block_id }, - |m: &mut BlockDelta| { &mut m.block_id }, + |m: &TextBlockDelta| { &m.block_id }, + |m: &mut TextBlockDelta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "delta_str", - |m: &BlockDelta| { &m.delta_str }, - |m: &mut BlockDelta| { &mut m.delta_str }, + |m: &TextBlockDelta| { &m.delta_str }, + |m: &mut TextBlockDelta| { &mut m.delta_str }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockDelta", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TextBlockDelta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockDelta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockDelta::new) + fn default_instance() -> &'static TextBlockDelta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TextBlockDelta::new) } } -impl ::protobuf::Clear for BlockDelta { +impl ::protobuf::Clear for TextBlockDelta { fn clear(&mut self) { self.block_id.clear(); self.delta_str.clear(); @@ -915,13 +915,13 @@ impl ::protobuf::Clear for BlockDelta { } } -impl ::std::fmt::Debug for BlockDelta { +impl ::std::fmt::Debug for TextBlockDelta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockDelta { +impl ::protobuf::reflect::ProtobufValue for TextBlockDelta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1164,7 +1164,7 @@ impl ::protobuf::reflect::ProtobufValue for NewDocUser { } #[derive(PartialEq,Clone,Default)] -pub struct BlockId { +pub struct TextBlockId { // message fields pub value: ::std::string::String, // special fields @@ -1172,14 +1172,14 @@ pub struct BlockId { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockId { - fn default() -> &'a BlockId { - ::default_instance() +impl<'a> ::std::default::Default for &'a TextBlockId { + fn default() -> &'a TextBlockId { + ::default_instance() } } -impl BlockId { - pub fn new() -> BlockId { +impl TextBlockId { + pub fn new() -> TextBlockId { ::std::default::Default::default() } @@ -1210,7 +1210,7 @@ impl BlockId { } } -impl ::protobuf::Message for BlockId { +impl ::protobuf::Message for TextBlockId { fn is_initialized(&self) -> bool { true } @@ -1276,8 +1276,8 @@ impl ::protobuf::Message for BlockId { Self::descriptor_static() } - fn new() -> BlockId { - BlockId::new() + fn new() -> TextBlockId { + TextBlockId::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1286,57 +1286,57 @@ impl ::protobuf::Message for BlockId { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "value", - |m: &BlockId| { &m.value }, - |m: &mut BlockId| { &mut m.value }, + |m: &TextBlockId| { &m.value }, + |m: &mut TextBlockId| { &mut m.value }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockId", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TextBlockId", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockId { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockId::new) + fn default_instance() -> &'static TextBlockId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TextBlockId::new) } } -impl ::protobuf::Clear for BlockId { +impl ::protobuf::Clear for TextBlockId { fn clear(&mut self) { self.value.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for BlockId { +impl ::std::fmt::Debug for TextBlockId { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockId { +impl ::protobuf::reflect::ProtobufValue for TextBlockId { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x13document_info.proto\x1a\x0erevision.proto\"T\n\x11CreateBlockParam\ - s\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\x02\ - \x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"q\n\tBlockInfo\x12\x19\ - \n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\x18\x02\ - \x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\ - \x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"^\n\x10Reset\ - BlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12/\n\ - \trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"D\n\ - \nBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\ - \x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nNewDocUser\x12\ - \x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\ - \x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05d\ - ocId\"\x1f\n\x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\ - \x06proto3\ + \n\x15text_block_info.proto\x1a\x0erevision.proto\"X\n\x15CreateTextBloc\ + kParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\ + \x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"u\n\rTextBlockInfo\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\ + \x18\x02\x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\ + \x05revId\x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"b\n\ + \x14ResetTextBlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\ + ockId\x12/\n\trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trev\ + isions\"H\n\x0eTextBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\ + \x07blockId\x12\x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nN\ + ewDocUser\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\ + \x06rev_id\x18\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\ + \x20\x01(\tR\x05docId\"#\n\x0bTextBlockId\x12\x14\n\x05value\x18\x01\x20\ + \x01(\tR\x05valueb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto b/shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto similarity index 76% rename from shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto rename to shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto index 9190b581a5..70717c4d2b 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto @@ -1,21 +1,21 @@ syntax = "proto3"; import "revision.proto"; -message CreateBlockParams { +message CreateTextBlockParams { string id = 1; RepeatedRevision revisions = 2; } -message BlockInfo { +message TextBlockInfo { string block_id = 1; string text = 2; int64 rev_id = 3; int64 base_rev_id = 4; } -message ResetBlockParams { +message ResetTextBlockParams { string block_id = 1; RepeatedRevision revisions = 2; } -message BlockDelta { +message TextBlockDelta { string block_id = 1; string delta_str = 2; } @@ -24,6 +24,6 @@ message NewDocUser { int64 rev_id = 2; string doc_id = 3; } -message BlockId { +message TextBlockId { string value = 1; } diff --git a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs index 37c3bf4f6a..8a5b5f7304 100644 --- a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs +++ b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs @@ -1,5 +1,5 @@ use crate::{ - entities::{document_info::BlockInfo, ws_data::ServerRevisionWSDataBuilder}, + entities::{text_block_info::TextBlockInfo, ws_data::ServerRevisionWSDataBuilder}, errors::{internal_error, CollaborateError, CollaborateResult}, protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, server_document::document_pad::ServerDocument, @@ -18,13 +18,13 @@ use tokio::{ }; pub trait DocumentCloudPersistence: Send + Sync + Debug { - fn read_document(&self, doc_id: &str) -> BoxResultFuture; + fn read_document(&self, doc_id: &str) -> BoxResultFuture; fn create_document( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture, CollaborateError>; + ) -> BoxResultFuture, CollaborateError>; fn read_document_revisions( &self, @@ -181,7 +181,7 @@ impl ServerDocumentManager { } } - async fn create_document_handler(&self, doc: BlockInfo) -> Result, CollaborateError> { + async fn create_document_handler(&self, doc: TextBlockInfo) -> Result, CollaborateError> { let persistence = self.persistence.clone(); let handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence)) .await @@ -205,7 +205,7 @@ struct OpenDocumentHandler { } impl OpenDocumentHandler { - fn new(doc: BlockInfo, persistence: Arc) -> Result { + fn new(doc: TextBlockInfo, persistence: Arc) -> Result { let doc_id = doc.block_id.clone(); let (sender, receiver) = mpsc::channel(1000); let users = DashMap::new(); diff --git a/shared-lib/flowy-collaboration/src/util.rs b/shared-lib/flowy-collaboration/src/util.rs index 6953949961..a3ea7b136e 100644 --- a/shared-lib/flowy-collaboration/src/util.rs +++ b/shared-lib/flowy-collaboration/src/util.rs @@ -1,13 +1,13 @@ use crate::{ entities::{ - document_info::BlockInfo, folder_info::{FolderDelta, FolderInfo}, revision::{RepeatedRevision, Revision}, + text_block_info::TextBlockInfo, }, errors::{CollaborateError, CollaborateResult}, protobuf::{ - BlockInfo as BlockInfoPB, FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, - Revision as RevisionPB, + FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB, + TextBlockInfo as TextBlockInfoPB, }, }; use dissimilar::Chunk; @@ -202,11 +202,11 @@ pub fn make_folder_pb_from_revisions_pb( pub fn make_document_info_from_revisions_pb( doc_id: &str, revisions: RepeatedRevisionPB, -) -> Result, CollaborateError> { +) -> Result, CollaborateError> { match make_document_info_pb_from_revisions_pb(doc_id, revisions)? { None => Ok(None), Some(pb) => { - let document_info: BlockInfo = pb.try_into().map_err(|e| { + let document_info: TextBlockInfo = pb.try_into().map_err(|e| { CollaborateError::internal().context(format!("Deserialize document info from pb failed: {}", e)) })?; Ok(Some(document_info)) @@ -218,7 +218,7 @@ pub fn make_document_info_from_revisions_pb( pub fn make_document_info_pb_from_revisions_pb( doc_id: &str, mut revisions: RepeatedRevisionPB, -) -> Result, CollaborateError> { +) -> Result, CollaborateError> { let revisions = revisions.take_items(); if revisions.is_empty() { return Ok(None); @@ -240,7 +240,7 @@ pub fn make_document_info_pb_from_revisions_pb( } let text = document_delta.to_delta_str(); - let mut block_info = BlockInfoPB::new(); + let mut block_info = TextBlockInfoPB::new(); block_info.set_block_id(doc_id.to_owned()); block_info.set_text(text); block_info.set_base_rev_id(base_rev_id); diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index ad85fe636b..e5f5c189cc 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,8 +1,6 @@ use crate::entities::{Field, RowMeta}; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use serde::{Deserialize, Serialize}; +use flowy_derive::ProtoBuf; use std::collections::HashMap; -use strum_macros::{Display, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_FIELD_WIDTH: i32 = 150; diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 22abf8905d..5fbd55ffa6 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,4 +1,3 @@ -use crate::entities::Row; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -16,14 +15,26 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub rows: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlock { +pub struct Block { #[pb(index = 1)] pub id: String, + #[pb(index = 2)] + pub start_row_index: i32, + + #[pb(index = 3)] + pub row_count: i32, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct BlockMeta { + #[pb(index = 1)] + pub block_id: String, + #[pb(index = 2)] pub rows: Vec, } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index deaa2a75c2..a542d09d7d 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub rows: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .RowMeta rows = 3; + // repeated .Block blocks = 3; - pub fn get_rows(&self) -> &[RowMeta] { - &self.rows + pub fn get_blocks(&self) -> &[Block] { + &self.blocks } - pub fn clear_rows(&mut self) { - self.rows.clear(); + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta { return false; } }; - for v in &self.rows { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.rows { + for value in &self.blocks { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.rows { + for v in &self.blocks { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -240,10 +240,10 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridMeta| { &m.rows }, - |m: &mut GridMeta| { &mut m.rows }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "blocks", + |m: &GridMeta| { &m.blocks }, + |m: &mut GridMeta| { &mut m.blocks }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridMeta", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta { fn clear(&mut self) { self.grid_id.clear(); self.fields.clear(); - self.rows.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } @@ -281,23 +281,24 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta { } #[derive(PartialEq,Clone,Default)] -pub struct GridBlock { +pub struct Block { // message fields pub id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, + pub start_row_index: i32, + pub row_count: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridBlock { - fn default() -> &'a GridBlock { - ::default_instance() +impl<'a> ::std::default::Default for &'a Block { + fn default() -> &'a Block { + ::default_instance() } } -impl GridBlock { - pub fn new() -> GridBlock { +impl Block { + pub fn new() -> Block { ::std::default::Default::default() } @@ -327,6 +328,234 @@ impl GridBlock { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } + // int32 start_row_index = 2; + + + pub fn get_start_row_index(&self) -> i32 { + self.start_row_index + } + pub fn clear_start_row_index(&mut self) { + self.start_row_index = 0; + } + + // Param is passed by value, moved + pub fn set_start_row_index(&mut self, v: i32) { + self.start_row_index = v; + } + + // int32 row_count = 3; + + + pub fn get_row_count(&self) -> i32 { + self.row_count + } + pub fn clear_row_count(&mut self) { + self.row_count = 0; + } + + // Param is passed by value, moved + pub fn set_row_count(&mut self, v: i32) { + self.row_count = v; + } +} + +impl ::protobuf::Message for Block { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.start_row_index = tmp; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.row_count = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if self.start_row_index != 0 { + my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); + } + if self.row_count != 0 { + my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if self.start_row_index != 0 { + os.write_int32(2, self.start_row_index)?; + } + if self.row_count != 0 { + os.write_int32(3, self.row_count)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Block { + Block::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &Block| { &m.id }, + |m: &mut Block| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "start_row_index", + |m: &Block| { &m.start_row_index }, + |m: &mut Block| { &mut m.start_row_index }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "row_count", + |m: &Block| { &m.row_count }, + |m: &mut Block| { &mut m.row_count }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Block", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Block { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Block::new) + } +} + +impl ::protobuf::Clear for Block { + fn clear(&mut self) { + self.id.clear(); + self.start_row_index = 0; + self.row_count = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Block { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Block { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct BlockMeta { + // message fields + pub block_id: ::std::string::String, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a BlockMeta { + fn default() -> &'a BlockMeta { + ::default_instance() + } +} + +impl BlockMeta { + pub fn new() -> BlockMeta { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + // repeated .RowMeta rows = 2; @@ -353,7 +582,7 @@ impl GridBlock { } } -impl ::protobuf::Message for GridBlock { +impl ::protobuf::Message for BlockMeta { fn is_initialized(&self) -> bool { for v in &self.rows { if !v.is_initialized() { @@ -368,7 +597,7 @@ impl ::protobuf::Message for GridBlock { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; @@ -385,8 +614,8 @@ impl ::protobuf::Message for GridBlock { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); } for value in &self.rows { let len = value.compute_size(); @@ -398,8 +627,8 @@ impl ::protobuf::Message for GridBlock { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; } for v in &self.rows { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; @@ -436,8 +665,8 @@ impl ::protobuf::Message for GridBlock { Self::descriptor_static() } - fn new() -> GridBlock { - GridBlock::new() + fn new() -> BlockMeta { + BlockMeta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -445,44 +674,44 @@ impl ::protobuf::Message for GridBlock { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &GridBlock| { &m.id }, - |m: &mut GridBlock| { &mut m.id }, + "block_id", + |m: &BlockMeta| { &m.block_id }, + |m: &mut BlockMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "rows", - |m: &GridBlock| { &m.rows }, - |m: &mut GridBlock| { &mut m.rows }, + |m: &BlockMeta| { &m.rows }, + |m: &mut BlockMeta| { &mut m.rows }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlock", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "BlockMeta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridBlock { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlock::new) + fn default_instance() -> &'static BlockMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(BlockMeta::new) } } -impl ::protobuf::Clear for GridBlock { +impl ::protobuf::Clear for BlockMeta { fn clear(&mut self) { - self.id.clear(); + self.block_id.clear(); self.rows.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for GridBlock { +impl ::std::fmt::Debug for BlockMeta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridBlock { +impl ::protobuf::reflect::ProtobufValue for BlockMeta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1997,34 +2226,36 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"a\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"c\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ - s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\ - dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\ - \x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\ - \x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\ - e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\ - \x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\ - \nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\ - \x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\ - \rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\ - tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\ - \x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\ - a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ - \x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\ - \x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ - \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ - \nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ - \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ - field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ - \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ - R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ - \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ - \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ - o3\ + s\x12\x1e\n\x06blocks\x18\x03\x20\x03(\x0b2\x06.BlockR\x06blocks\"\\\n\ + \x05Block\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_\ + index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ + \x20\x01(\x05R\x08rowCount\"D\n\tBlockMeta\x12\x19\n\x08block_id\x18\x01\ + \x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.RowM\ + etaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ + FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ + n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ + idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ + \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ + items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\ + \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\ + \x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ + \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\ + dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\ + ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\ + ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ + \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\x82\x01\ + \n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06ro\ + w_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\ + \tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04d\ + ata\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\ + \x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Date\ + Time\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\ + \x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 24149d1fa0..f3757d40ed 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,10 +3,15 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated Field fields = 2; - repeated RowMeta rows = 3; + repeated Block blocks = 3; } -message GridBlock { +message Block { string id = 1; + int32 start_row_index = 2; + int32 row_count = 3; +} +message BlockMeta { + string block_id = 1; repeated RowMeta rows = 2; } message Field { diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 203651a9a0..2d1495e811 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -7,14 +7,14 @@ fn grid_serde_test() { let grid = GridMeta { grid_id, fields, - rows: vec![], + blocks: vec![], }; let grid_1_json = serde_json::to_string(&grid).unwrap(); - let _: Grid = serde_json::from_str(&grid_1_json).unwrap(); + let _: GridMeta = serde_json::from_str(&grid_1_json).unwrap(); assert_eq!( grid_1_json, - r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"rows":[]}"# + r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"blocks":[]}"# ) } @@ -24,11 +24,11 @@ fn grid_default_serde_test() { let grid = GridMeta { grid_id, fields: vec![], - rows: vec![], + blocks: vec![], }; let json = serde_json::to_string(&grid).unwrap(); - assert_eq!(json, r#"{"id":"1","fields":[],"row_orders":[]}"#) + assert_eq!(json, r#"{"id":"1","fields":[],"blocks":[]}"#) } fn create_field(field_id: &str) -> Field { From cea7d30a53425503dbf7531592d037acc7df8978 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 21:43:23 +0800 Subject: [PATCH 028/179] chore: config BlockMetaPad --- .../flowy-grid-data-model/meta.pb.dart | 109 +++++ .../flowy-grid-data-model/meta.pbjson.dart | 28 ++ frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../tests/editor/attribute_test.rs | 10 +- .../flowy-block/tests/editor/serde_test.rs | 6 +- .../src/client_document/default/mod.rs | 2 +- .../src/client_document/document_pad.rs | 2 +- .../src/client_folder/folder_pad.rs | 6 +- .../src/client_grid/block_pad.rs | 181 +++++++-- .../src/entities/meta.rs | 19 +- .../src/protobuf/model/meta.rs | 380 ++++++++++++++++-- .../src/protobuf/proto/meta.proto | 8 +- shared-lib/lib-ot/src/core/delta/delta.rs | 4 +- 13 files changed, 684 insertions(+), 75 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 4ac91c7ff1..8ca629edfa 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -552,6 +552,115 @@ class RowMeta extends $pb.GeneratedMessage { void clearVisibility() => clearField(5); } +enum RowMetaChangeset_OneOfHeight { + height, + notSet +} + +enum RowMetaChangeset_OneOfVisibility { + visibility, + notSet +} + +class RowMetaChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, RowMetaChangeset_OneOfHeight> _RowMetaChangeset_OneOfHeightByTag = { + 2 : RowMetaChangeset_OneOfHeight.height, + 0 : RowMetaChangeset_OneOfHeight.notSet + }; + static const $core.Map<$core.int, RowMetaChangeset_OneOfVisibility> _RowMetaChangeset_OneOfVisibilityByTag = { + 3 : RowMetaChangeset_OneOfVisibility.visibility, + 0 : RowMetaChangeset_OneOfVisibility.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMetaChangeset', createEmptyInstance: create) + ..oo(0, [2]) + ..oo(1, [3]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..m<$core.String, CellMeta>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMetaChangeset.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) + ..hasRequiredFields = false + ; + + RowMetaChangeset._() : super(); + factory RowMetaChangeset({ + $core.String? rowId, + $core.int? height, + $core.bool? visibility, + $core.Map<$core.String, CellMeta>? cellByFieldId, + }) { + final _result = create(); + if (rowId != null) { + _result.rowId = rowId; + } + if (height != null) { + _result.height = height; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (cellByFieldId != null) { + _result.cellByFieldId.addAll(cellByFieldId); + } + return _result; + } + factory RowMetaChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RowMetaChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RowMetaChangeset clone() => RowMetaChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RowMetaChangeset copyWith(void Function(RowMetaChangeset) updates) => super.copyWith((message) => updates(message as RowMetaChangeset)) as RowMetaChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RowMetaChangeset create() => RowMetaChangeset._(); + RowMetaChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RowMetaChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RowMetaChangeset? _defaultInstance; + + RowMetaChangeset_OneOfHeight whichOneOfHeight() => _RowMetaChangeset_OneOfHeightByTag[$_whichOneof(0)]!; + void clearOneOfHeight() => clearField($_whichOneof(0)); + + RowMetaChangeset_OneOfVisibility whichOneOfVisibility() => _RowMetaChangeset_OneOfVisibilityByTag[$_whichOneof(1)]!; + void clearOneOfVisibility() => clearField($_whichOneof(1)); + + @$pb.TagNumber(1) + $core.String get rowId => $_getSZ(0); + @$pb.TagNumber(1) + set rowId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasRowId() => $_has(0); + @$pb.TagNumber(1) + void clearRowId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get height => $_getIZ(1); + @$pb.TagNumber(2) + set height($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasHeight() => $_has(1); + @$pb.TagNumber(2) + void clearHeight() => clearField(2); + + @$pb.TagNumber(3) + $core.bool get visibility => $_getBF(2); + @$pb.TagNumber(3) + set visibility($core.bool v) { $_setBool(2, v); } + @$pb.TagNumber(3) + $core.bool hasVisibility() => $_has(2); + @$pb.TagNumber(3) + void clearVisibility() => clearField(3); + + @$pb.TagNumber(4) + $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(3); +} + class CellMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index d0d94fd269..89b7a3c88b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -121,6 +121,34 @@ const RowMeta_CellByFieldIdEntry$json = const { /// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use rowMetaChangesetDescriptor instead') +const RowMetaChangeset$json = const { + '1': 'RowMetaChangeset', + '2': const [ + const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'height', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'height'}, + const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '9': 1, '10': 'visibility'}, + const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.RowMetaChangeset.CellByFieldIdEntry', '10': 'cellByFieldId'}, + ], + '3': const [RowMetaChangeset_CellByFieldIdEntry$json], + '8': const [ + const {'1': 'one_of_height'}, + const {'1': 'one_of_visibility'}, + ], +}; + +@$core.Deprecated('Use rowMetaChangesetDescriptor instead') +const RowMetaChangeset_CellByFieldIdEntry$json = const { + '1': 'CellByFieldIdEntry', + '2': const [ + const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `RowMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode('ChBSb3dNZXRhQ2hhbmdlc2V0EhUKBnJvd19pZBgBIAEoCVIFcm93SWQSGAoGaGVpZ2h0GAIgASgFSABSBmhlaWdodBIgCgp2aXNpYmlsaXR5GAMgASgISAFSCnZpc2liaWxpdHkSTQoQY2VsbF9ieV9maWVsZF9pZBgEIAMoCzIkLlJvd01ldGFDaGFuZ2VzZXQuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGksKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIfCgV2YWx1ZRgCIAEoCzIJLkNlbGxNZXRhUgV2YWx1ZToCOAFCDwoNb25lX29mX2hlaWdodEITChFvbmVfb2ZfdmlzaWJpbGl0eQ=='); @$core.Deprecated('Use cellMetaDescriptor instead') const CellMeta$json = const { '1': 'CellMeta', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 96755db623..046fd85668 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default staticlib -crate-type = ["staticlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs b/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs index fb91e8125c..264cee831b 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs @@ -762,12 +762,12 @@ fn attributes_preserve_list_format_on_merge() { #[test] fn delta_compose() { - let mut delta = RichTextDelta::from_json(r#"[{"insert":"\n"}]"#).unwrap(); + let mut delta = RichTextDelta::from_delta_str(r#"[{"insert":"\n"}]"#).unwrap(); let deltas = vec![ - RichTextDelta::from_json(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(), - RichTextDelta::from_json(r#"[{"insert":"a"}]"#).unwrap(), - RichTextDelta::from_json(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(), - RichTextDelta::from_json(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"insert":"a"}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(), ]; for d in deltas { diff --git a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs b/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs index 71c5e64dc3..54c7f92152 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs @@ -65,7 +65,7 @@ fn delta_serialize_multi_attribute_test() { let json = serde_json::to_string(&delta).unwrap(); eprintln!("{}", json); - let delta_from_json = Delta::from_json(&json).unwrap(); + let delta_from_json = Delta::from_delta_str(&json).unwrap(); assert_eq!(delta_from_json, delta); } @@ -77,7 +77,7 @@ fn delta_deserialize_test() { {"retain":2,"attributes":{"italic":"true","bold":"true"}}, {"retain":2,"attributes":{"italic":true,"bold":true}} ]"#; - let delta = RichTextDelta::from_json(json).unwrap(); + let delta = RichTextDelta::from_delta_str(json).unwrap(); eprintln!("{}", delta); } @@ -86,7 +86,7 @@ fn delta_deserialize_null_test() { let json = r#"[ {"retain":7,"attributes":{"bold":null}} ]"#; - let delta1 = RichTextDelta::from_json(json).unwrap(); + let delta1 = RichTextDelta::from_delta_str(json).unwrap(); let mut attribute = RichTextAttribute::Bold(true); attribute.value = RichTextAttributeValue(None); diff --git a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs b/shared-lib/flowy-collaboration/src/client_document/default/mod.rs index be6b679c81..f5fb180571 100644 --- a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_document/default/mod.rs @@ -13,7 +13,7 @@ pub fn initial_quill_delta_string() -> String { #[inline] pub fn initial_read_me() -> RichTextDelta { let json = include_str!("READ_ME.json"); - RichTextDelta::from_json(json).unwrap() + RichTextDelta::from_delta_str(json).unwrap() } #[cfg(test)] diff --git a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs index 0a537a8c8d..4807d9869c 100644 --- a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs @@ -54,7 +54,7 @@ impl ClientDocument { } pub fn from_json(json: &str) -> Result { - let delta = RichTextDelta::from_json(json)?; + let delta = RichTextDelta::from_delta_str(json)?; Ok(Self::from_delta(delta)) } diff --git a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs index 455f12c002..4fd8a1982e 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs @@ -307,7 +307,7 @@ impl FolderPad { if let Some(workspace) = workspaces.iter_mut().find(|workspace| workspace_id == workspace.id) { f(Arc::make_mut(workspace)) } else { - tracing::warn!("[RootFolder]: Can't find any workspace with id: {}", workspace_id); + tracing::warn!("[FolderPad]: Can't find any workspace with id: {}", workspace_id); Ok(None) } }) @@ -344,7 +344,7 @@ impl FolderPad { .find(|workspace| workspace.apps.iter().any(|app| app.id == app_id)) { None => { - tracing::warn!("[RootFolder]: Can't find any app with id: {}", app_id); + tracing::warn!("[FolderPad]: Can't find any app with id: {}", app_id); return Ok(None); } Some(workspace) => workspace.id.clone(), @@ -363,7 +363,7 @@ impl FolderPad { self.with_app(belong_to_id, |app| { match app.belongings.iter_mut().find(|view| view_id == view.id) { None => { - tracing::warn!("[RootFolder]: Can't find any view with id: {}", view_id); + tracing::warn!("[FolderPad]: Can't find any view with id: {}", view_id); Ok(None) } Some(view) => f(view), diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 23f07e3efb..54f4b67967 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,30 +1,33 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowOrder}; +use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowMetaChangeset, RowOrder}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use serde::{Deserialize, Serialize}; use std::sync::Arc; pub type BlockMetaDelta = PlainTextDelta; pub type BlockDeltaBuilder = PlainTextDeltaBuilder; +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct BlockMetaPad { - pub(crate) block_meta: Arc, + block_id: String, + rows: Vec>, + + #[serde(skip)] pub(crate) delta: BlockMetaDelta, } impl BlockMetaPad { pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_delta: BlockMeta = serde_json::from_str(&s).map_err(|e| { + let block_meta: BlockMeta = serde_json::from_str(&s).map_err(|e| { CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) })?; - - Ok(Self { - block_meta: Arc::new(block_delta), - delta, - }) + let block_id = block_meta.block_id; + let rows = block_meta.rows.into_iter().map(Arc::new).collect::>>(); + Ok(Self { block_id, rows, delta }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { @@ -32,38 +35,55 @@ impl BlockMetaPad { Self::from_delta(block_delta) } - pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { - self.modify(|grid| { - grid.rows.push(row); + pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { + self.modify(|rows| { + rows.push(Arc::new(row)); Ok(Some(())) }) } pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { - self.modify(|grid| { - grid.rows.retain(|row| !row_ids.contains(&row.id)); + self.modify(|rows| { + rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } - pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) - } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + let row_id = changeset.row_id.clone(); + self.modify_row(&row_id, |row| { + let mut is_changed = None; + if let Some(height) = changeset.height { + row.height = height; + is_changed = Some(()); + } - pub fn delta_str(&self) -> String { - self.delta.to_delta_str() + if let Some(visibility) = changeset.visibility { + row.visibility = visibility; + is_changed = Some(()); + } + + if !changeset.cell_by_field_id.is_empty() { + is_changed = Some(()); + changeset.cell_by_field_id.into_iter().for_each(|(field_id, cell)| { + row.cell_by_field_id.insert(field_id, cell); + }) + } + + Ok(is_changed) + }) } pub fn modify(&mut self, f: F) -> CollaborateResult> where - F: FnOnce(&mut BlockMeta) -> CollaborateResult>, + F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { - let cloned_meta = self.block_meta.clone(); - match f(Arc::make_mut(&mut self.block_meta))? { + let cloned_self = self.clone(); + match f(&mut self.rows)? { None => Ok(None), Some(_) => { - let old = json_from_grid(&cloned_meta)?; - let new = json_from_grid(&self.block_meta)?; + let old = cloned_self.to_json()?; + let new = self.to_json()?; match cal_diff::(old, new) { None => Ok(None), Some(delta) => { @@ -74,6 +94,33 @@ impl BlockMetaPad { } } } + + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + where + F: FnOnce(&mut RowMeta) -> CollaborateResult>, + { + self.modify(|rows| { + if let Some(row_meta) = rows.iter_mut().find(|row_meta| row_id == row_meta.id) { + f(Arc::make_mut(row_meta)) + } else { + tracing::warn!("[BlockMetaPad]: Can't find any row with id: {}", row_id); + Ok(None) + } + }) + } + + pub fn to_json(&self) -> CollaborateResult { + serde_json::to_string(self) + .map_err(|e| CollaborateError::internal().context(format!("serial trash to json failed: {}", e))) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) + } + + pub fn delta_str(&self) -> String { + self.delta.to_delta_str() + } } fn json_from_grid(block_meta: &Arc) -> CollaborateResult { @@ -106,10 +153,96 @@ impl std::default::Default for BlockMetaPad { block_id: uuid(), rows: vec![], }; + let delta = make_block_meta_delta(&block_meta); BlockMetaPad { - block_meta: Arc::new(block_meta), + block_id: block_meta.block_id, + rows: block_meta.rows.into_iter().map(Arc::new).collect::>(), delta, } } } + +#[cfg(test)] +mod tests { + use crate::client_grid::{BlockMetaDelta, BlockMetaPad}; + use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; + use std::str::FromStr; + + #[test] + fn block_meta_add_row() { + let mut pad = test_pad(); + let row = RowMeta { + id: "1".to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + }; + + let change = pad.add_row(row).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + ); + } + + #[test] + fn block_meta_delete_row() { + let mut pad = test_pad(); + let pre_delta_str = pad.delta_str(); + let row = RowMeta { + id: "1".to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + }; + + let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":24},{"delete":77},{"retain":2}]"# + ); + + assert_eq!(pad.delta_str(), pre_delta_str); + } + + #[test] + fn block_meta_update_row() { + let mut pad = test_pad(); + let row = RowMeta { + id: "1".to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + }; + + let changeset = RowMetaChangeset { + row_id: row.id.clone(), + height: Some(100), + visibility: Some(true), + cell_by_field_id: Default::default(), + }; + + let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let change = pad.update_row(changeset).unwrap().unwrap(); + + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":80},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# + ); + + assert_eq!( + pad.to_json().unwrap(), + r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# + ); + } + + fn test_pad() -> BlockMetaPad { + let delta = BlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); + BlockMetaPad::from_delta(delta).unwrap() + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 5fbd55ffa6..e8483dcb02 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -178,7 +178,7 @@ pub struct RowMeta { pub id: String, #[pb(index = 2)] - pub grid_id: String, + pub block_id: String, #[pb(index = 3)] pub cell_by_field_id: HashMap, @@ -199,7 +199,7 @@ impl RowMeta { Self { id: id.to_owned(), - grid_id: grid_id.to_owned(), + block_id: grid_id.to_owned(), cell_by_field_id, height: DEFAULT_ROW_HEIGHT, visibility: true, @@ -207,6 +207,21 @@ impl RowMeta { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct RowMetaChangeset { + #[pb(index = 1)] + pub row_id: String, + + #[pb(index = 2, one_of)] + pub height: Option, + + #[pb(index = 3, one_of)] + pub visibility: Option, + + #[pb(index = 4)] + pub cell_by_field_id: HashMap, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct CellMeta { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index a542d09d7d..4107603b67 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -1524,7 +1524,7 @@ impl ::protobuf::reflect::ProtobufValue for AnyData { pub struct RowMeta { // message fields pub id: ::std::string::String, - pub grid_id: ::std::string::String, + pub block_id: ::std::string::String, pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, pub height: i32, pub visibility: bool, @@ -1570,30 +1570,30 @@ impl RowMeta { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // string grid_id = 2; + // string block_id = 2; - pub fn get_grid_id(&self) -> &str { - &self.grid_id + pub fn get_block_id(&self) -> &str { + &self.block_id } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); + pub fn clear_block_id(&mut self) { + self.block_id.clear(); } // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id } // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } // repeated .RowMeta.CellByFieldIdEntry cell_by_field_id = 3; @@ -1665,7 +1665,7 @@ impl ::protobuf::Message for RowMeta { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 3 => { ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; @@ -1699,8 +1699,8 @@ impl ::protobuf::Message for RowMeta { if !self.id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.id); } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_id); + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.block_id); } my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); if self.height != 0 { @@ -1718,8 +1718,8 @@ impl ::protobuf::Message for RowMeta { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_id)?; + if !self.block_id.is_empty() { + os.write_string(2, &self.block_id)?; } ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; if self.height != 0 { @@ -1772,9 +1772,9 @@ impl ::protobuf::Message for RowMeta { |m: &mut RowMeta| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &RowMeta| { &m.grid_id }, - |m: &mut RowMeta| { &mut m.grid_id }, + "block_id", + |m: &RowMeta| { &m.block_id }, + |m: &mut RowMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( "cell_by_field_id", @@ -1808,7 +1808,7 @@ impl ::protobuf::Message for RowMeta { impl ::protobuf::Clear for RowMeta { fn clear(&mut self) { self.id.clear(); - self.grid_id.clear(); + self.block_id.clear(); self.cell_by_field_id.clear(); self.height = 0; self.visibility = false; @@ -1828,6 +1828,317 @@ impl ::protobuf::reflect::ProtobufValue for RowMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct RowMetaChangeset { + // message fields + pub row_id: ::std::string::String, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, + // message oneof groups + pub one_of_height: ::std::option::Option, + pub one_of_visibility: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RowMetaChangeset { + fn default() -> &'a RowMetaChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum RowMetaChangeset_oneof_one_of_height { + height(i32), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum RowMetaChangeset_oneof_one_of_visibility { + visibility(bool), +} + +impl RowMetaChangeset { + pub fn new() -> RowMetaChangeset { + ::std::default::Default::default() + } + + // string row_id = 1; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // int32 height = 2; + + + pub fn get_height(&self) -> i32 { + match self.one_of_height { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(v)) => v, + _ => 0, + } + } + pub fn clear_height(&mut self) { + self.one_of_height = ::std::option::Option::None; + } + + pub fn has_height(&self) -> bool { + match self.one_of_height { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.one_of_height = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(v)) + } + + // bool visibility = 3; + + + pub fn get_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(v)) => v, + _ => false, + } + } + pub fn clear_visibility(&mut self) { + self.one_of_visibility = ::std::option::Option::None; + } + + pub fn has_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.one_of_visibility = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(v)) + } + + // repeated .RowMetaChangeset.CellByFieldIdEntry cell_by_field_id = 4; + + + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { + &self.cell_by_field_id + } + pub fn clear_cell_by_field_id(&mut self) { + self.cell_by_field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { + self.cell_by_field_id = v; + } + + // Mutable pointer to the field. + pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { + &mut self.cell_by_field_id + } + + // Take field + pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { + ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) + } +} + +impl ::protobuf::Message for RowMetaChangeset { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_height = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(is.read_int32()?)); + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_visibility = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); + }, + 4 => { + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.row_id); + } + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id); + if let ::std::option::Option::Some(ref v) = self.one_of_height { + match v { + &RowMetaChangeset_oneof_one_of_height::height(v) => { + my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &RowMetaChangeset_oneof_one_of_visibility::visibility(v) => { + my_size += 2; + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.row_id.is_empty() { + os.write_string(1, &self.row_id)?; + } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, os)?; + if let ::std::option::Option::Some(ref v) = self.one_of_height { + match v { + &RowMetaChangeset_oneof_one_of_height::height(v) => { + os.write_int32(2, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &RowMetaChangeset_oneof_one_of_visibility::visibility(v) => { + os.write_bool(3, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RowMetaChangeset { + RowMetaChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &RowMetaChangeset| { &m.row_id }, + |m: &mut RowMetaChangeset| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "height", + RowMetaChangeset::has_height, + RowMetaChangeset::get_height, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "visibility", + RowMetaChangeset::has_visibility, + RowMetaChangeset::get_visibility, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + "cell_by_field_id", + |m: &RowMetaChangeset| { &m.cell_by_field_id }, + |m: &mut RowMetaChangeset| { &mut m.cell_by_field_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RowMetaChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RowMetaChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RowMetaChangeset::new) + } +} + +impl ::protobuf::Clear for RowMetaChangeset { + fn clear(&mut self) { + self.row_id.clear(); + self.one_of_height = ::std::option::Option::None; + self.one_of_visibility = ::std::option::Option::None; + self.cell_by_field_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RowMetaChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RowMetaChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CellMeta { // message fields @@ -2242,20 +2553,27 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\ \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\ - \x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ + \x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\ \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\ dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\ ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\ ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ - \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\x82\x01\ - \n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06ro\ - w_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\ - \tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04d\ - ata\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\ - \x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Date\ - Time\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\ - \x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\ + \n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ + ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ + \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ + dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ + \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\x01\n\ + \x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06row_\ + id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\ + R\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04dat\ + a\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\x12\ + \x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\ + \x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\ + \x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index f3757d40ed..dc00b1e72c 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -33,11 +33,17 @@ message AnyData { } message RowMeta { string id = 1; - string grid_id = 2; + string block_id = 2; map cell_by_field_id = 3; int32 height = 4; bool visibility = 5; } +message RowMetaChangeset { + string row_id = 1; + oneof one_of_height { int32 height = 2; }; + oneof one_of_visibility { bool visibility = 3; }; + map cell_by_field_id = 4; +} message CellMeta { string id = 1; string row_id = 2; diff --git a/shared-lib/lib-ot/src/core/delta/delta.rs b/shared-lib/lib-ot/src/core/delta/delta.rs index e9a7e15e12..ac4fcbbef5 100644 --- a/shared-lib/lib-ot/src/core/delta/delta.rs +++ b/shared-lib/lib-ot/src/core/delta/delta.rs @@ -501,7 +501,7 @@ impl Delta where T: Attributes + DeserializeOwned, { - pub fn from_json(json: &str) -> Result { + pub fn from_delta_str(json: &str) -> Result { let delta = serde_json::from_str(json).map_err(|e| { tracing::trace!("Deserialize failed: {:?}", e); tracing::trace!("{:?}", json); @@ -512,7 +512,7 @@ where pub fn from_bytes>(bytes: B) -> Result { let json = str::from_utf8(bytes.as_ref())?.to_owned(); - let val = Self::from_json(&json)?; + let val = Self::from_delta_str(&json)?; Ok(val) } } From 9a791974b44bf866348e85414850100f3bd0e8fa Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 22:27:19 +0800 Subject: [PATCH 029/179] chore: config grid rev persistence --- .../flowy-collaboration/revision.pbenum.dart | 15 - .../flowy-collaboration/revision.pbjson.dart | 11 - .../flowy-grid-data-model/meta.pb.dart | 16 +- .../flowy-grid-data-model/meta.pbjson.dart | 4 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-database/src/schema.rs | 12 + .../src/services/persistence/mod.rs | 17 +- .../src/cache/disk/grid_rev_impl.rs | 272 ++++++++++++++++++ .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 47 ++- ...ext_block_rev_impl.rs => text_rev_impl.rs} | 102 +++---- .../rust-lib/flowy-sync/src/cache/memory.rs | 3 +- frontend/rust-lib/flowy-sync/src/cache/mod.rs | 2 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 3 +- .../flowy-sync/src/rev_persistence.rs | 24 +- .../src/entities/revision.rs | 21 -- .../src/protobuf/model/revision.rs | 53 +--- .../src/protobuf/proto/revision.proto | 4 - 17 files changed, 404 insertions(+), 206 deletions(-) rename frontend/rust-lib/flowy-sync/src/cache/disk/{text_block_rev_impl.rs => text_rev_impl.rs} (72%) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart index 4c2ae91cea..f3c7efb417 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart @@ -9,21 +9,6 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -class RevisionState extends $pb.ProtobufEnum { - static const RevisionState Sync = RevisionState._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Sync'); - static const RevisionState Ack = RevisionState._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ack'); - - static const $core.List values = [ - Sync, - Ack, - ]; - - static final $core.Map<$core.int, RevisionState> _byValue = $pb.ProtobufEnum.initByValue(values); - static RevisionState? valueOf($core.int value) => _byValue[value]; - - const RevisionState._($core.int v, $core.String n) : super(v, n); -} - class RevType extends $pb.ProtobufEnum { static const RevType DeprecatedLocal = RevType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeprecatedLocal'); static const RevType DeprecatedRemote = RevType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeprecatedRemote'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart index 64a4feed7e..5d4db67b74 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart @@ -8,17 +8,6 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use revisionStateDescriptor instead') -const RevisionState$json = const { - '1': 'RevisionState', - '2': const [ - const {'1': 'Sync', '2': 0}, - const {'1': 'Ack', '2': 1}, - ], -}; - -/// Descriptor for `RevisionState`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List revisionStateDescriptor = $convert.base64Decode('Cg1SZXZpc2lvblN0YXRlEggKBFN5bmMQABIHCgNBY2sQAQ=='); @$core.Deprecated('Use revTypeDescriptor instead') const RevType$json = const { '1': 'RevType', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 8ca629edfa..924cb4addb 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -458,7 +458,7 @@ class AnyData extends $pb.GeneratedMessage { class RowMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMeta.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') @@ -468,7 +468,7 @@ class RowMeta extends $pb.GeneratedMessage { RowMeta._() : super(); factory RowMeta({ $core.String? id, - $core.String? gridId, + $core.String? blockId, $core.Map<$core.String, CellMeta>? cellByFieldId, $core.int? height, $core.bool? visibility, @@ -477,8 +477,8 @@ class RowMeta extends $pb.GeneratedMessage { if (id != null) { _result.id = id; } - if (gridId != null) { - _result.gridId = gridId; + if (blockId != null) { + _result.blockId = blockId; } if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); @@ -522,13 +522,13 @@ class RowMeta extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - $core.String get gridId => $_getSZ(1); + $core.String get blockId => $_getSZ(1); @$pb.TagNumber(2) - set gridId($core.String v) { $_setString(1, v); } + set blockId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasGridId() => $_has(1); + $core.bool hasBlockId() => $_has(1); @$pb.TagNumber(2) - void clearGridId() => clearField(2); + void clearBlockId() => clearField(2); @$pb.TagNumber(3) $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(2); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 89b7a3c88b..5685a4c17b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -101,7 +101,7 @@ const RowMeta$json = const { '1': 'RowMeta', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellByFieldIdEntry', '10': 'cellByFieldId'}, const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'}, @@ -120,7 +120,7 @@ const RowMeta_CellByFieldIdEntry$json = const { }; /// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); +final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIZCghibG9ja19pZBgCIAEoCVIHYmxvY2tJZBJEChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhsuUm93TWV0YS5DZWxsQnlGaWVsZElkRW50cnlSDWNlbGxCeUZpZWxkSWQSFgoGaGVpZ2h0GAQgASgFUgZoZWlnaHQSHgoKdmlzaWJpbGl0eRgFIAEoCFIKdmlzaWJpbGl0eRpLChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHwoFdmFsdWUYAiABKAsyCS5DZWxsTWV0YVIFdmFsdWU6AjgB'); @$core.Deprecated('Use rowMetaChangesetDescriptor instead') const RowMetaChangeset$json = const { '1': 'RowMetaChangeset', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-database/src/schema.rs b/frontend/rust-lib/flowy-database/src/schema.rs index aa7200000e..7397f5b704 100644 --- a/frontend/rust-lib/flowy-database/src/schema.rs +++ b/frontend/rust-lib/flowy-database/src/schema.rs @@ -21,6 +21,17 @@ table! { } } +table! { + grid_rev_table (id) { + id -> Integer, + object_id -> Text, + base_rev_id -> BigInt, + rev_id -> BigInt, + data -> Binary, + state -> Integer, + } +} + table! { kv_table (key) { key -> Text, @@ -91,6 +102,7 @@ table! { allow_tables_to_appear_in_same_query!( app_table, doc_table, + grid_rev_table, kv_table, rev_table, trash_table, diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs index fa473ea063..b05490b70a 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -2,20 +2,13 @@ mod migration; pub mod version_1; mod version_2; -use flowy_collaboration::client_folder::initial_folder_delta; -use flowy_collaboration::{ - client_folder::FolderPad, - entities::revision::{Revision, RevisionState}, -}; -use std::sync::Arc; -use tokio::sync::RwLock; -pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; - use crate::{ event_map::WorkspaceDatabase, manager::FolderId, services::{folder_editor::ClientFolderEditor, persistence::migration::FolderMigration}, }; +use flowy_collaboration::client_folder::initial_folder_delta; +use flowy_collaboration::{client_folder::FolderPad, entities::revision::Revision}; use flowy_error::{FlowyError, FlowyResult}; use flowy_folder_data_model::entities::{ app::App, @@ -23,8 +16,12 @@ use flowy_folder_data_model::entities::{ view::View, workspace::Workspace, }; -use flowy_sync::{mk_revision_disk_cache, RevisionRecord}; +use flowy_sync::disk::{RevisionRecord, RevisionState}; +use flowy_sync::mk_revision_disk_cache; use lib_sqlite::ConnectionPool; +use std::sync::Arc; +use tokio::sync::RwLock; +pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; pub trait FolderPersistenceTransaction { fn create_workspace(&self, user_id: &str, workspace: Workspace) -> FlowyResult<()>; diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs index e69de29bb2..6053b17133 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs @@ -0,0 +1,272 @@ +use crate::cache::disk::RevisionDiskCache; +use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use bytes::Bytes; +use diesel::{sql_types::Integer, update, SqliteConnection}; +use flowy_collaboration::{ + entities::revision::{RevId, RevType, Revision, RevisionRange}, + util::md5, +}; +use flowy_database::{ + impl_sql_integer_expression, insert_or_ignore_into, + prelude::*, + schema::{grid_rev_table, grid_rev_table::dsl}, + ConnectionPool, +}; +use flowy_error::{internal_error, FlowyError, FlowyResult}; +use std::sync::Arc; + +pub struct SQLiteGridRevisionPersistence { + user_id: String, + pub(crate) pool: Arc, +} + +impl RevisionDiskCache for SQLiteGridRevisionPersistence { + type Error = FlowyError; + + fn create_revision_records( + &self, + revision_records: Vec, + conn: &SqliteConnection, + ) -> Result<(), Self::Error> { + let _ = GridRevisionSql::create(revision_records, conn)?; + Ok(()) + } + + fn read_revision_records( + &self, + object_id: &str, + rev_ids: Option>, + ) -> Result, Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let records = GridRevisionSql::read(&self.user_id, object_id, rev_ids, &*conn)?; + Ok(records) + } + + fn read_revision_records_with_range( + &self, + object_id: &str, + range: &RevisionRange, + ) -> Result, Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let revisions = GridRevisionSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; + Ok(revisions) + } + + fn update_revision_record(&self, changesets: Vec) -> FlowyResult<()> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = conn.immediate_transaction::<_, FlowyError, _>(|| { + for changeset in changesets { + let _ = GridRevisionSql::update(changeset, conn)?; + } + Ok(()) + })?; + Ok(()) + } + + fn delete_revision_records(&self, object_id: &str, rev_ids: Option>) -> Result<(), Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = GridRevisionSql::delete(object_id, rev_ids, conn)?; + Ok(()) + } + + fn delete_and_insert_records( + &self, + object_id: &str, + deleted_rev_ids: Option>, + inserted_records: Vec, + ) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + conn.immediate_transaction::<_, FlowyError, _>(|| { + let _ = GridRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; + let _ = self.create_revision_records(inserted_records, &*conn)?; + Ok(()) + }) + } +} + +impl SQLiteGridRevisionPersistence { + pub(crate) fn new(user_id: &str, pool: Arc) -> Self { + Self { + user_id: user_id.to_owned(), + pool, + } + } +} + +struct GridRevisionSql(); +impl GridRevisionSql { + fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { + // Batch insert: https://diesel.rs/guides/all-about-inserts.html + + let records = revision_records + .into_iter() + .map(|record| { + tracing::trace!( + "[GridRevisionSql] create revision: {}:{:?}", + record.revision.object_id, + record.revision.rev_id + ); + let rev_state: GridRevisionState = record.state.into(); + ( + dsl::object_id.eq(record.revision.object_id), + dsl::base_rev_id.eq(record.revision.base_rev_id), + dsl::rev_id.eq(record.revision.rev_id), + dsl::data.eq(record.revision.delta_data), + dsl::state.eq(rev_state), + ) + }) + .collect::>(); + + let _ = insert_or_ignore_into(dsl::grid_rev_table) + .values(&records) + .execute(conn)?; + Ok(()) + } + + fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + let state: GridRevisionState = changeset.state.clone().into(); + let filter = dsl::grid_rev_table + .filter(dsl::rev_id.eq(changeset.rev_id.as_ref())) + .filter(dsl::object_id.eq(changeset.object_id)); + let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?; + tracing::debug!( + "[GridRevisionSql] update revision:{} state:to {:?}", + changeset.rev_id, + changeset.state + ); + Ok(()) + } + + fn read( + user_id: &str, + object_id: &str, + rev_ids: Option>, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let mut sql = dsl::grid_rev_table.filter(dsl::object_id.eq(object_id)).into_boxed(); + if let Some(rev_ids) = rev_ids { + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + let rows = sql.order(dsl::rev_id.asc()).load::(conn)?; + let records = rows + .into_iter() + .map(|row| mk_revision_record_from_table(user_id, row)) + .collect::>(); + + Ok(records) + } + + fn read_with_range( + user_id: &str, + object_id: &str, + range: RevisionRange, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let rev_tables = dsl::grid_rev_table + .filter(dsl::rev_id.ge(range.start)) + .filter(dsl::rev_id.le(range.end)) + .filter(dsl::object_id.eq(object_id)) + .order(dsl::rev_id.asc()) + .load::(conn)?; + + let revisions = rev_tables + .into_iter() + .map(|table| mk_revision_record_from_table(user_id, table)) + .collect::>(); + Ok(revisions) + } + + fn delete(object_id: &str, rev_ids: Option>, conn: &SqliteConnection) -> Result<(), FlowyError> { + let mut sql = diesel::delete(dsl::grid_rev_table).into_boxed(); + sql = sql.filter(dsl::object_id.eq(object_id)); + + if let Some(rev_ids) = rev_ids { + tracing::trace!("[GridRevisionSql] Delete revision: {}:{:?}", object_id, rev_ids); + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + + let affected_row = sql.execute(conn)?; + tracing::trace!("[GridRevisionSql] Delete {} rows", affected_row); + Ok(()) + } +} + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] +#[table_name = "grid_rev_table"] +pub(crate) struct GridRevisionTable { + id: i32, + pub(crate) object_id: String, + pub(crate) base_rev_id: i64, + pub(crate) rev_id: i64, + pub(crate) data: Vec, + pub(crate) state: GridRevisionState, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] +#[repr(i32)] +#[sql_type = "Integer"] +pub enum GridRevisionState { + Sync = 0, + Ack = 1, +} + +impl std::default::Default for GridRevisionState { + fn default() -> Self { + GridRevisionState::Sync + } +} + +impl std::convert::From for GridRevisionState { + fn from(value: i32) -> Self { + match value { + 0 => GridRevisionState::Sync, + 1 => GridRevisionState::Ack, + o => { + tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); + GridRevisionState::Sync + } + } + } +} + +impl GridRevisionState { + pub fn value(&self) -> i32 { + *self as i32 + } +} +impl_sql_integer_expression!(GridRevisionState); + +impl std::convert::From for RevisionState { + fn from(s: GridRevisionState) -> Self { + match s { + GridRevisionState::Sync => RevisionState::Sync, + GridRevisionState::Ack => RevisionState::Ack, + } + } +} + +impl std::convert::From for GridRevisionState { + fn from(s: RevisionState) -> Self { + match s { + RevisionState::Sync => GridRevisionState::Sync, + RevisionState::Ack => GridRevisionState::Ack, + } + } +} + +fn mk_revision_record_from_table(user_id: &str, table: GridRevisionTable) -> RevisionRecord { + let md5 = md5(&table.data); + let revision = Revision::new( + &table.object_id, + table.base_rev_id, + table.rev_id, + Bytes::from(table.data), + user_id, + md5, + ); + RevisionRecord { + revision, + state: table.state.into(), + write_to_disk: false, + } +} diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index 6c3ee45f37..4fcad2d2ec 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -1,14 +1,13 @@ mod folder_rev_impl; mod grid_rev_impl; -mod text_block_rev_impl; +mod text_rev_impl; pub use folder_rev_impl::*; pub use grid_rev_impl::*; -pub use text_block_rev_impl::*; +pub use text_rev_impl::*; -use crate::RevisionRecord; use diesel::SqliteConnection; -use flowy_collaboration::entities::revision::RevisionRange; +use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; use std::fmt::Debug; @@ -48,3 +47,43 @@ pub trait RevisionDiskCache: Sync + Send { inserted_records: Vec, ) -> Result<(), Self::Error>; } + +#[derive(Clone, Debug)] +pub struct RevisionRecord { + pub revision: Revision, + pub state: RevisionState, + pub write_to_disk: bool, +} + +impl RevisionRecord { + pub fn ack(&mut self) { + self.state = RevisionState::Ack; + } +} + +pub struct RevisionChangeset { + pub(crate) object_id: String, + pub(crate) rev_id: RevId, + pub(crate) state: RevisionState, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum RevisionState { + Sync = 0, + Ack = 1, +} + +impl RevisionState { + pub fn is_need_sync(&self) -> bool { + match self { + RevisionState::Sync => true, + RevisionState::Ack => false, + } + } +} + +impl AsRef for RevisionState { + fn as_ref(&self) -> &RevisionState { + self + } +} diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs similarity index 72% rename from frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs rename to frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs index d7b56034c3..7659ad33dc 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs @@ -1,8 +1,9 @@ -use crate::{cache::disk::RevisionDiskCache, RevisionRecord}; +use crate::cache::disk::RevisionDiskCache; +use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange, RevisionState}, + entities::revision::{RevId, RevType, Revision, RevisionRange}, util::md5, }; use flowy_database::{ @@ -27,7 +28,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { revision_records: Vec, conn: &SqliteConnection, ) -> Result<(), Self::Error> { - let _ = RevisionTableSql::create(revision_records, conn)?; + let _ = TextRevisionSql::create(revision_records, conn)?; Ok(()) } @@ -37,7 +38,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { rev_ids: Option>, ) -> Result, Self::Error> { let conn = self.pool.get().map_err(internal_error)?; - let records = RevisionTableSql::read(&self.user_id, object_id, rev_ids, &*conn)?; + let records = TextRevisionSql::read(&self.user_id, object_id, rev_ids, &*conn)?; Ok(records) } @@ -47,7 +48,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { range: &RevisionRange, ) -> Result, Self::Error> { let conn = &*self.pool.get().map_err(internal_error)?; - let revisions = RevisionTableSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; + let revisions = TextRevisionSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; Ok(revisions) } @@ -55,7 +56,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { let conn = &*self.pool.get().map_err(internal_error)?; let _ = conn.immediate_transaction::<_, FlowyError, _>(|| { for changeset in changesets { - let _ = RevisionTableSql::update(changeset, conn)?; + let _ = TextRevisionSql::update(changeset, conn)?; } Ok(()) })?; @@ -64,7 +65,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { fn delete_revision_records(&self, object_id: &str, rev_ids: Option>) -> Result<(), Self::Error> { let conn = &*self.pool.get().map_err(internal_error)?; - let _ = RevisionTableSql::delete(object_id, rev_ids, conn)?; + let _ = TextRevisionSql::delete(object_id, rev_ids, conn)?; Ok(()) } @@ -76,7 +77,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { ) -> Result<(), Self::Error> { let conn = self.pool.get().map_err(internal_error)?; conn.immediate_transaction::<_, FlowyError, _>(|| { - let _ = RevisionTableSql::delete(object_id, deleted_rev_ids, &*conn)?; + let _ = TextRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; let _ = self.create_revision_records(inserted_records, &*conn)?; Ok(()) }) @@ -92,21 +93,21 @@ impl SQLiteTextBlockRevisionPersistence { } } -pub struct RevisionTableSql {} +struct TextRevisionSql {} -impl RevisionTableSql { - pub(crate) fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { +impl TextRevisionSql { + fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { // Batch insert: https://diesel.rs/guides/all-about-inserts.html let records = revision_records .into_iter() .map(|record| { tracing::trace!( - "[RevisionTable] create revision: {}:{:?}", + "[TextRevisionSql] create revision: {}:{:?}", record.revision.object_id, record.revision.rev_id ); - let rev_state: RevisionTableState = record.state.into(); + let rev_state: TextRevisionState = record.state.into(); ( dsl::doc_id.eq(record.revision.object_id), dsl::base_rev_id.eq(record.revision.base_rev_id), @@ -122,20 +123,21 @@ impl RevisionTableSql { Ok(()) } - pub(crate) fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + let state: TextRevisionState = changeset.state.clone().into(); let filter = dsl::rev_table .filter(dsl::rev_id.eq(changeset.rev_id.as_ref())) .filter(dsl::doc_id.eq(changeset.object_id)); - let _ = update(filter).set(dsl::state.eq(changeset.state)).execute(conn)?; + let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?; tracing::debug!( - "[RevisionTable] update revision:{} state:to {:?}", + "[TextRevisionSql] update revision:{} state:to {:?}", changeset.rev_id, changeset.state ); Ok(()) } - pub(crate) fn read( + fn read( user_id: &str, object_id: &str, rev_ids: Option>, @@ -154,7 +156,7 @@ impl RevisionTableSql { Ok(records) } - pub(crate) fn read_with_range( + fn read_with_range( user_id: &str, object_id: &str, range: RevisionRange, @@ -174,90 +176,86 @@ impl RevisionTableSql { Ok(revisions) } - pub(crate) fn delete( - object_id: &str, - rev_ids: Option>, - conn: &SqliteConnection, - ) -> Result<(), FlowyError> { + fn delete(object_id: &str, rev_ids: Option>, conn: &SqliteConnection) -> Result<(), FlowyError> { let mut sql = diesel::delete(dsl::rev_table).into_boxed(); sql = sql.filter(dsl::doc_id.eq(object_id)); if let Some(rev_ids) = rev_ids { - tracing::trace!("[RevisionTable] Delete revision: {}:{:?}", object_id, rev_ids); + tracing::trace!("[TextRevisionSql] Delete revision: {}:{:?}", object_id, rev_ids); sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); } let affected_row = sql.execute(conn)?; - tracing::trace!("[RevisionTable] Delete {} rows", affected_row); + tracing::trace!("[TextRevisionSql] Delete {} rows", affected_row); Ok(()) } } #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[table_name = "rev_table"] -pub(crate) struct RevisionTable { +struct RevisionTable { id: i32, - pub(crate) doc_id: String, - pub(crate) base_rev_id: i64, - pub(crate) rev_id: i64, - pub(crate) data: Vec, - pub(crate) state: RevisionTableState, - pub(crate) ty: RevTableType, // Deprecated + doc_id: String, + base_rev_id: i64, + rev_id: i64, + data: Vec, + state: TextRevisionState, + ty: RevTableType, // Deprecated } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] #[repr(i32)] #[sql_type = "Integer"] -pub enum RevisionTableState { +enum TextRevisionState { Sync = 0, Ack = 1, } -impl std::default::Default for RevisionTableState { +impl std::default::Default for TextRevisionState { fn default() -> Self { - RevisionTableState::Sync + TextRevisionState::Sync } } -impl std::convert::From for RevisionTableState { +impl std::convert::From for TextRevisionState { fn from(value: i32) -> Self { match value { - 0 => RevisionTableState::Sync, - 1 => RevisionTableState::Ack, + 0 => TextRevisionState::Sync, + 1 => TextRevisionState::Ack, o => { tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); - RevisionTableState::Sync + TextRevisionState::Sync } } } } -impl RevisionTableState { +impl TextRevisionState { pub fn value(&self) -> i32 { *self as i32 } } -impl_sql_integer_expression!(RevisionTableState); +impl_sql_integer_expression!(TextRevisionState); -impl std::convert::From for RevisionState { - fn from(s: RevisionTableState) -> Self { +impl std::convert::From for RevisionState { + fn from(s: TextRevisionState) -> Self { match s { - RevisionTableState::Sync => RevisionState::Sync, - RevisionTableState::Ack => RevisionState::Ack, + TextRevisionState::Sync => RevisionState::Sync, + TextRevisionState::Ack => RevisionState::Ack, } } } -impl std::convert::From for RevisionTableState { +impl std::convert::From for TextRevisionState { fn from(s: RevisionState) -> Self { match s { - RevisionState::Sync => RevisionTableState::Sync, - RevisionState::Ack => RevisionTableState::Ack, + RevisionState::Sync => TextRevisionState::Sync, + RevisionState::Ack => TextRevisionState::Ack, } } } -pub(crate) fn mk_revision_record_from_table(user_id: &str, table: RevisionTable) -> RevisionRecord { +fn mk_revision_record_from_table(user_id: &str, table: RevisionTable) -> RevisionRecord { let md5 = md5(&table.data); let revision = Revision::new( &table.doc_id, @@ -324,9 +322,3 @@ impl std::convert::From for RevType { } } } - -pub struct RevisionChangeset { - pub(crate) object_id: String, - pub(crate) rev_id: RevId, - pub(crate) state: RevisionTableState, -} diff --git a/frontend/rust-lib/flowy-sync/src/cache/memory.rs b/frontend/rust-lib/flowy-sync/src/cache/memory.rs index 2c99c3f08c..f709abcdd2 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/memory.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/memory.rs @@ -1,4 +1,5 @@ -use crate::{RevisionRecord, REVISION_WRITE_INTERVAL_IN_MILLIS}; +use crate::disk::RevisionRecord; +use crate::REVISION_WRITE_INTERVAL_IN_MILLIS; use dashmap::DashMap; use flowy_collaboration::entities::revision::RevisionRange; use flowy_error::{FlowyError, FlowyResult}; diff --git a/frontend/rust-lib/flowy-sync/src/cache/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/mod.rs index 9ef6fb7da0..3e592c49b1 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/mod.rs @@ -1,2 +1,2 @@ -pub(crate) mod disk; +pub mod disk; pub(crate) mod memory; diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index 5583690913..ab5d7858b3 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -1,6 +1,7 @@ +use crate::disk::RevisionState; use crate::{RevisionPersistence, WSDataProviderDataSource}; use flowy_collaboration::{ - entities::revision::{RepeatedRevision, Revision, RevisionRange, RevisionState}, + entities::revision::{RepeatedRevision, Revision, RevisionRange}, util::{pair_rev_id_from_revisions, RevIdCounter}, }; use flowy_error::{FlowyError, FlowyResult}; diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs index 428e708916..d6b129170f 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs @@ -1,13 +1,12 @@ use crate::cache::{ - disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLiteTextBlockRevisionPersistence}, + disk::{RevisionChangeset, RevisionDiskCache, SQLiteTextBlockRevisionPersistence}, memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, }; - -use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState}; +use crate::disk::{RevisionRecord, RevisionState}; +use crate::RevisionCompact; +use flowy_collaboration::entities::revision::{Revision, RevisionRange}; use flowy_database::ConnectionPool; use flowy_error::{internal_error, FlowyError, FlowyResult}; - -use crate::RevisionCompact; use std::collections::VecDeque; use std::{borrow::Cow, sync::Arc}; use tokio::sync::RwLock; @@ -235,7 +234,7 @@ impl RevisionMemoryCacheDelegate for Arc { let changeset = RevisionChangeset { object_id: object_id.to_string(), rev_id: rev_id.into(), - state: RevisionTableState::Ack, + state: RevisionState::Ack, }; match self.update_revision_record(vec![changeset]) { Ok(_) => {} @@ -244,19 +243,6 @@ impl RevisionMemoryCacheDelegate for Arc { } } -#[derive(Clone, Debug)] -pub struct RevisionRecord { - pub revision: Revision, - pub state: RevisionState, - pub write_to_disk: bool, -} - -impl RevisionRecord { - pub fn ack(&mut self) { - self.state = RevisionState::Ack; - } -} - #[derive(Default)] struct RevisionSyncSequence(VecDeque); impl RevisionSyncSequence { diff --git a/shared-lib/flowy-collaboration/src/entities/revision.rs b/shared-lib/flowy-collaboration/src/entities/revision.rs index cd99a194a1..57276bba1b 100644 --- a/shared-lib/flowy-collaboration/src/entities/revision.rs +++ b/shared-lib/flowy-collaboration/src/entities/revision.rs @@ -215,27 +215,6 @@ pub fn md5>(data: T) -> String { md5 } -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum RevisionState { - Sync = 0, - Ack = 1, -} - -impl RevisionState { - pub fn is_need_sync(&self) -> bool { - match self { - RevisionState::Sync => true, - RevisionState::Ack => false, - } - } -} - -impl AsRef for RevisionState { - fn as_ref(&self) -> &RevisionState { - self - } -} - #[derive(Debug, ProtoBuf_Enum, Clone, Eq, PartialEq)] pub enum RevType { DeprecatedLocal = 0, diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs b/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs index 079687ca44..02d1f522cf 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs @@ -914,56 +914,6 @@ impl ::protobuf::reflect::ProtobufValue for RevisionRange { } } -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum RevisionState { - Sync = 0, - Ack = 1, -} - -impl ::protobuf::ProtobufEnum for RevisionState { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(RevisionState::Sync), - 1 => ::std::option::Option::Some(RevisionState::Ack), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [RevisionState] = &[ - RevisionState::Sync, - RevisionState::Ack, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("RevisionState", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for RevisionState { -} - -impl ::std::default::Default for RevisionState { - fn default() -> Self { - RevisionState::Sync - } -} - -impl ::protobuf::reflect::ProtobufValue for RevisionState { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum RevType { DeprecatedLocal = 0, @@ -1024,8 +974,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x10RepeatedRevision\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.Revision\ R\x05items\"\x1d\n\x05RevId\x12\x14\n\x05value\x18\x01\x20\x01(\x03R\x05\ value\"7\n\rRevisionRange\x12\x14\n\x05start\x18\x01\x20\x01(\x03R\x05st\ - art\x12\x10\n\x03end\x18\x02\x20\x01(\x03R\x03end*\"\n\rRevisionState\ - \x12\x08\n\x04Sync\x10\0\x12\x07\n\x03Ack\x10\x01*4\n\x07RevType\x12\x13\ + art\x12\x10\n\x03end\x18\x02\x20\x01(\x03R\x03end*4\n\x07RevType\x12\x13\ \n\x0fDeprecatedLocal\x10\0\x12\x14\n\x10DeprecatedRemote\x10\x01b\x06pr\ oto3\ "; diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto b/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto index 34c37409ab..5e899e9688 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto @@ -19,10 +19,6 @@ message RevisionRange { int64 start = 1; int64 end = 2; } -enum RevisionState { - Sync = 0; - Ack = 1; -} enum RevType { DeprecatedLocal = 0; DeprecatedRemote = 1; From e11176436d4c76a0ccfaf84e004258c19d2c061d Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 11 Mar 2022 21:36:00 +0800 Subject: [PATCH 030/179] chore: grid block meta editor --- .../flowy-grid-data-model/meta.pb.dart | 296 ++++++- .../flowy-grid-data-model/meta.pbjson.dart | 50 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- frontend/rust-lib/flowy-block/src/editor.rs | 6 +- frontend/rust-lib/flowy-block/src/manager.rs | 14 +- frontend/rust-lib/flowy-block/src/queue.rs | 28 +- .../2022-03-04-101530_flowy-grid/down.sql | 3 +- .../2022-03-04-101530_flowy-grid/up.sql | 9 - .../2022-03-11-025536_flowy-grid/down.sql | 3 + .../2022-03-11-025536_flowy-grid/up.sql | 18 + .../rust-lib/flowy-database/src/macros.rs | 36 + .../rust-lib/flowy-database/src/schema.rs | 12 + frontend/rust-lib/flowy-folder/src/manager.rs | 10 +- .../src/services/folder_editor.rs | 40 +- .../src/services/persistence/migration.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 5 +- .../flowy-grid/src/services/grid_editor.rs | 217 +++-- .../src/services/grid_meta_editor.rs | 125 +++ .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../flowy-sdk/src/deps_resolve/folder_deps.rs | 12 +- .../src/cache/disk/grid_meta_rev_impl.rs | 235 +++++ .../src/cache/disk/grid_rev_impl.rs | 66 +- .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 9 +- .../src/cache/disk/text_rev_impl.rs | 61 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 40 +- .../flowy-sync/src/rev_persistence.rs | 34 +- .../src/client_grid/block_pad.rs | 54 +- .../src/client_grid/grid_pad.rs | 149 +++- .../src/entities/grid.rs | 3 - .../src/entities/meta.rs | 43 +- .../src/protobuf/model/meta.rs | 813 ++++++++++++++++-- .../src/protobuf/proto/meta.proto | 16 +- 32 files changed, 1887 insertions(+), 529 deletions(-) create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql create mode 100644 frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs create mode 100644 frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 924cb4addb..3b5d6f5dad 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: Block.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlock.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blocks, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -73,19 +73,19 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); + $core.List get blocks => $_getList(2); } -class Block extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Block', createEmptyInstance: create) +class GridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) ..hasRequiredFields = false ; - Block._() : super(); - factory Block({ + GridBlock._() : super(); + factory GridBlock({ $core.String? id, $core.int? startRowIndex, $core.int? rowCount, @@ -102,26 +102,26 @@ class Block extends $pb.GeneratedMessage { } return _result; } - factory Block.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Block.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - Block clone() => Block()..mergeFromMessage(this); + GridBlock clone() => GridBlock()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - Block copyWith(void Function(Block) updates) => super.copyWith((message) => updates(message as Block)) as Block; // ignore: deprecated_member_use + GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static Block create() => Block._(); - Block createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlock create() => GridBlock._(); + GridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static Block getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Block? _defaultInstance; + static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlock? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -151,15 +151,15 @@ class Block extends $pb.GeneratedMessage { void clearRowCount() => clearField(3); } -class BlockMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockMeta', createEmptyInstance: create) +class GridBlockMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..hasRequiredFields = false ; - BlockMeta._() : super(); - factory BlockMeta({ + GridBlockMeta._() : super(); + factory GridBlockMeta({ $core.String? blockId, $core.Iterable? rows, }) { @@ -172,26 +172,26 @@ class BlockMeta extends $pb.GeneratedMessage { } return _result; } - factory BlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - BlockMeta clone() => BlockMeta()..mergeFromMessage(this); + GridBlockMeta clone() => GridBlockMeta()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - BlockMeta copyWith(void Function(BlockMeta) updates) => super.copyWith((message) => updates(message as BlockMeta)) as BlockMeta; // ignore: deprecated_member_use + GridBlockMeta copyWith(void Function(GridBlockMeta) updates) => super.copyWith((message) => updates(message as GridBlockMeta)) as GridBlockMeta; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static BlockMeta create() => BlockMeta._(); - BlockMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlockMeta create() => GridBlockMeta._(); + GridBlockMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static BlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static BlockMeta? _defaultInstance; + static GridBlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMeta? _defaultInstance; @$pb.TagNumber(1) $core.String get blockId => $_getSZ(0); @@ -394,6 +394,244 @@ class RepeatedField extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } +enum FieldChangeset_OneOfName { + name, + notSet +} + +enum FieldChangeset_OneOfDesc { + desc, + notSet +} + +enum FieldChangeset_OneOfFieldType { + fieldType, + notSet +} + +enum FieldChangeset_OneOfFrozen { + frozen, + notSet +} + +enum FieldChangeset_OneOfVisibility { + visibility, + notSet +} + +enum FieldChangeset_OneOfWidth { + width, + notSet +} + +enum FieldChangeset_OneOfTypeOptions { + typeOptions, + notSet +} + +class FieldChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, FieldChangeset_OneOfName> _FieldChangeset_OneOfNameByTag = { + 2 : FieldChangeset_OneOfName.name, + 0 : FieldChangeset_OneOfName.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfDesc> _FieldChangeset_OneOfDescByTag = { + 3 : FieldChangeset_OneOfDesc.desc, + 0 : FieldChangeset_OneOfDesc.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfFieldType> _FieldChangeset_OneOfFieldTypeByTag = { + 4 : FieldChangeset_OneOfFieldType.fieldType, + 0 : FieldChangeset_OneOfFieldType.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfFrozen> _FieldChangeset_OneOfFrozenByTag = { + 5 : FieldChangeset_OneOfFrozen.frozen, + 0 : FieldChangeset_OneOfFrozen.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfVisibility> _FieldChangeset_OneOfVisibilityByTag = { + 6 : FieldChangeset_OneOfVisibility.visibility, + 0 : FieldChangeset_OneOfVisibility.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfWidth> _FieldChangeset_OneOfWidthByTag = { + 7 : FieldChangeset_OneOfWidth.width, + 0 : FieldChangeset_OneOfWidth.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfTypeOptions> _FieldChangeset_OneOfTypeOptionsByTag = { + 8 : FieldChangeset_OneOfTypeOptions.typeOptions, + 0 : FieldChangeset_OneOfTypeOptions.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangeset', createEmptyInstance: create) + ..oo(0, [2]) + ..oo(1, [3]) + ..oo(2, [4]) + ..oo(3, [5]) + ..oo(4, [6]) + ..oo(5, [7]) + ..oo(6, [8]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..hasRequiredFields = false + ; + + FieldChangeset._() : super(); + factory FieldChangeset({ + $core.String? fieldId, + $core.String? name, + $core.String? desc, + FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + AnyData? typeOptions, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + if (typeOptions != null) { + _result.typeOptions = typeOptions; + } + return _result; + } + factory FieldChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + FieldChangeset clone() => FieldChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldChangeset copyWith(void Function(FieldChangeset) updates) => super.copyWith((message) => updates(message as FieldChangeset)) as FieldChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldChangeset create() => FieldChangeset._(); + FieldChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldChangeset? _defaultInstance; + + FieldChangeset_OneOfName whichOneOfName() => _FieldChangeset_OneOfNameByTag[$_whichOneof(0)]!; + void clearOneOfName() => clearField($_whichOneof(0)); + + FieldChangeset_OneOfDesc whichOneOfDesc() => _FieldChangeset_OneOfDescByTag[$_whichOneof(1)]!; + void clearOneOfDesc() => clearField($_whichOneof(1)); + + FieldChangeset_OneOfFieldType whichOneOfFieldType() => _FieldChangeset_OneOfFieldTypeByTag[$_whichOneof(2)]!; + void clearOneOfFieldType() => clearField($_whichOneof(2)); + + FieldChangeset_OneOfFrozen whichOneOfFrozen() => _FieldChangeset_OneOfFrozenByTag[$_whichOneof(3)]!; + void clearOneOfFrozen() => clearField($_whichOneof(3)); + + FieldChangeset_OneOfVisibility whichOneOfVisibility() => _FieldChangeset_OneOfVisibilityByTag[$_whichOneof(4)]!; + void clearOneOfVisibility() => clearField($_whichOneof(4)); + + FieldChangeset_OneOfWidth whichOneOfWidth() => _FieldChangeset_OneOfWidthByTag[$_whichOneof(5)]!; + void clearOneOfWidth() => clearField($_whichOneof(5)); + + FieldChangeset_OneOfTypeOptions whichOneOfTypeOptions() => _FieldChangeset_OneOfTypeOptionsByTag[$_whichOneof(6)]!; + void clearOneOfTypeOptions() => clearField($_whichOneof(6)); + + @$pb.TagNumber(1) + $core.String get fieldId => $_getSZ(0); + @$pb.TagNumber(1) + set fieldId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFieldId() => $_has(0); + @$pb.TagNumber(1) + void clearFieldId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get desc => $_getSZ(2); + @$pb.TagNumber(3) + set desc($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDesc() => $_has(2); + @$pb.TagNumber(3) + void clearDesc() => clearField(3); + + @$pb.TagNumber(4) + FieldType get fieldType => $_getN(3); + @$pb.TagNumber(4) + set fieldType(FieldType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasFieldType() => $_has(3); + @$pb.TagNumber(4) + void clearFieldType() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get frozen => $_getBF(4); + @$pb.TagNumber(5) + set frozen($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrozen() => $_has(4); + @$pb.TagNumber(5) + void clearFrozen() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get visibility => $_getBF(5); + @$pb.TagNumber(6) + set visibility($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasVisibility() => $_has(5); + @$pb.TagNumber(6) + void clearVisibility() => clearField(6); + + @$pb.TagNumber(7) + $core.int get width => $_getIZ(6); + @$pb.TagNumber(7) + set width($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasWidth() => $_has(6); + @$pb.TagNumber(7) + void clearWidth() => clearField(7); + + @$pb.TagNumber(8) + AnyData get typeOptions => $_getN(7); + @$pb.TagNumber(8) + set typeOptions(AnyData v) { setField(8, v); } + @$pb.TagNumber(8) + $core.bool hasTypeOptions() => $_has(7); + @$pb.TagNumber(8) + void clearTypeOptions() => clearField(8); + @$pb.TagNumber(8) + AnyData ensureTypeOptions() => $_ensure(7); +} + class AnyData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 5685a4c17b..c955a005fb 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,15 +29,15 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.Block', '10': 'blocks'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlock', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIeCgZibG9ja3MYAyADKAsyBi5CbG9ja1IGYmxvY2tz'); -@$core.Deprecated('Use blockDescriptor instead') -const Block$json = const { - '1': 'Block', +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIiCgZibG9ja3MYAyADKAsyCi5HcmlkQmxvY2tSBmJsb2Nrcw=='); +@$core.Deprecated('Use gridBlockDescriptor instead') +const GridBlock$json = const { + '1': 'GridBlock', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, @@ -45,19 +45,19 @@ const Block$json = const { ], }; -/// Descriptor for `Block`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockDescriptor = $convert.base64Decode('CgVCbG9jaxIOCgJpZBgBIAEoCVICaWQSJgoPc3RhcnRfcm93X2luZGV4GAIgASgFUg1zdGFydFJvd0luZGV4EhsKCXJvd19jb3VudBgDIAEoBVIIcm93Q291bnQ='); -@$core.Deprecated('Use blockMetaDescriptor instead') -const BlockMeta$json = const { - '1': 'BlockMeta', +/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); +@$core.Deprecated('Use gridBlockMetaDescriptor instead') +const GridBlockMeta$json = const { + '1': 'GridBlockMeta', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, ], }; -/// Descriptor for `BlockMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockMetaDescriptor = $convert.base64Decode('CglCbG9ja01ldGESGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSHAoEcm93cxgCIAMoCzIILlJvd01ldGFSBHJvd3M='); +/// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', @@ -85,6 +85,32 @@ const RepeatedField$json = const { /// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); +@$core.Deprecated('Use fieldChangesetDescriptor instead') +const FieldChangeset$json = const { + '1': 'FieldChangeset', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'name'}, + const {'1': 'desc', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'desc'}, + const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'}, + const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, + const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, + const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '9': 6, '10': 'typeOptions'}, + ], + '8': const [ + const {'1': 'one_of_name'}, + const {'1': 'one_of_desc'}, + const {'1': 'one_of_field_type'}, + const {'1': 'one_of_frozen'}, + const {'1': 'one_of_visibility'}, + const {'1': 'one_of_width'}, + const {'1': 'one_of_type_options'}, + ], +}; + +/// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 96755db623..046fd85668 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default staticlib -crate-type = ["staticlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs index d7977c19db..fa3c1c757c 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -1,4 +1,4 @@ -use crate::queue::BlockRevisionCompact; +use crate::queue::TextBlockRevisionCompactor; use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; use crate::{ errors::FlowyError, @@ -40,9 +40,7 @@ impl ClientTextBlockEditor { rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { - let document_info = rev_manager - .load::(cloud_service) - .await?; + let document_info = rev_manager.load::(cloud_service).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index 091ca31bec..a08dc9b7b1 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -8,6 +8,7 @@ use flowy_collaboration::entities::{ }; use flowy_database::ConnectionPool; use flowy_error::FlowyResult; +use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_infra::future::FutureResult; use std::{convert::TryInto, sync::Arc}; @@ -84,7 +85,7 @@ impl TextBlockManager { let doc_id = doc_id.as_ref().to_owned(); let db_pool = self.user.db_pool()?; // Maybe we could save the block to disk without creating the RevisionManager - let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?; + let rev_manager = self.make_rev_manager(&doc_id, db_pool)?; let _ = rev_manager.reset_object(revisions).await?; Ok(()) } @@ -111,20 +112,20 @@ impl TextBlockManager { match self.editor_map.get(block_id) { None => { let db_pool = self.user.db_pool()?; - self.make_block_editor(block_id, db_pool).await + self.make_text_block_editor(block_id, db_pool).await } Some(editor) => Ok(editor), } } - async fn make_block_editor( + async fn make_text_block_editor( &self, block_id: &str, pool: Arc, ) -> Result, FlowyError> { let user = self.user.clone(); let token = self.user.token()?; - let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?; + let rev_manager = self.make_rev_manager(block_id, pool.clone())?; let cloud_service = Arc::new(TextBlockRevisionCloudService { token, server: self.cloud_service.clone(), @@ -135,9 +136,10 @@ impl TextBlockManager { Ok(doc_editor) } - fn make_block_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { + fn make_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { let user_id = self.user.user_id()?; - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool)); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, disk_cache)); Ok(RevisionManager::new(&user_id, doc_id, rev_persistence)) } } diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index aaaca7dbb4..c7683e9f0f 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -1,6 +1,7 @@ use crate::web_socket::EditorCommandReceiver; use crate::TextBlockUser; use async_stream::stream; +use bytes::Bytes; use flowy_collaboration::util::make_delta_from_revisions; use flowy_collaboration::{ client_document::{history::UndoResult, ClientDocument}, @@ -8,8 +9,9 @@ use flowy_collaboration::{ errors::CollaborateError, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_sync::{DeltaMD5, RevisionCompact, RevisionManager, RichTextTransformDeltas, TransformDeltas}; +use flowy_sync::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas}; use futures::stream::StreamExt; +use lib_ot::core::{Attributes, Delta}; use lib_ot::{ core::{Interval, OperationTransformable}, rich_text::{RichTextAttribute, RichTextAttributes, RichTextDelta}, @@ -187,31 +189,17 @@ impl EditBlockQueue { ); let _ = self .rev_manager - .add_local_revision::(&revision) + .add_local_revision(&revision, Box::new(TextBlockRevisionCompactor())) .await?; Ok(rev_id.into()) } } -pub(crate) struct BlockRevisionCompact(); -impl RevisionCompact for BlockRevisionCompact { - fn compact_revisions(user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { - if revisions.is_empty() { - return Err(FlowyError::internal().context("Can't compact the empty block's revisions")); - } - - if revisions.len() == 1 { - return Ok(revisions.pop().unwrap()); - } - - let first_revision = revisions.first().unwrap(); - let last_revision = revisions.last().unwrap(); - - let (base_rev_id, rev_id) = first_revision.pair_rev_id(); - let md5 = last_revision.md5.clone(); +pub(crate) struct TextBlockRevisionCompactor(); +impl RevisionCompactor for TextBlockRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - let delta_data = delta.to_bytes(); - Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + Ok(delta.to_bytes()) } } diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql index 1447085d7f..96473ec177 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql @@ -1,3 +1,2 @@ -- This file should undo anything in `up.sql` -DROP TABLE kv_table; -DROP TABLE grid_rev_table; \ No newline at end of file +DROP TABLE kv_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql index c8b592109b..edde5d7dfa 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql @@ -2,13 +2,4 @@ CREATE TABLE kv_table ( key TEXT NOT NULL PRIMARY KEY, value BLOB NOT NULL DEFAULT (x'') -); - -CREATE TABLE grid_rev_table ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - object_id TEXT NOT NULL DEFAULT '', - base_rev_id BIGINT NOT NULL DEFAULT 0, - rev_id BIGINT NOT NULL DEFAULT 0, - data BLOB NOT NULL DEFAULT (x''), - state INTEGER NOT NULL DEFAULT 0 ); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql new file mode 100644 index 0000000000..9d48f0fb8a --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +DROP TABLE grid_rev_table; +DROP TABLE grid_meta_rev_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql new file mode 100644 index 0000000000..4ce278ec8f --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql @@ -0,0 +1,18 @@ +-- Your SQL goes here +CREATE TABLE grid_rev_table ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + object_id TEXT NOT NULL DEFAULT '', + base_rev_id BIGINT NOT NULL DEFAULT 0, + rev_id BIGINT NOT NULL DEFAULT 0, + data BLOB NOT NULL DEFAULT (x''), + state INTEGER NOT NULL DEFAULT 0 +); + +CREATE TABLE grid_meta_rev_table ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + object_id TEXT NOT NULL DEFAULT '', + base_rev_id BIGINT NOT NULL DEFAULT 0, + rev_id BIGINT NOT NULL DEFAULT 0, + data BLOB NOT NULL DEFAULT (x''), + state INTEGER NOT NULL DEFAULT 0 +); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/src/macros.rs b/frontend/rust-lib/flowy-database/src/macros.rs index 9ef9740fee..e1534bf25f 100644 --- a/frontend/rust-lib/flowy-database/src/macros.rs +++ b/frontend/rust-lib/flowy-database/src/macros.rs @@ -160,3 +160,39 @@ macro_rules! impl_sql_integer_expression { } }; } + +#[macro_export] +macro_rules! impl_rev_state_map { + ($target:ident) => { + impl std::convert::From for $target { + fn from(value: i32) -> Self { + match value { + 0 => $target::Sync, + 1 => $target::Ack, + o => { + tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); + $target::Sync + } + } + } + } + + impl std::convert::From<$target> for RevisionState { + fn from(s: $target) -> Self { + match s { + $target::Sync => RevisionState::Sync, + $target::Ack => RevisionState::Ack, + } + } + } + + impl std::convert::From for $target { + fn from(s: RevisionState) -> Self { + match s { + RevisionState::Sync => $target::Sync, + RevisionState::Ack => $target::Ack, + } + } + } + }; +} diff --git a/frontend/rust-lib/flowy-database/src/schema.rs b/frontend/rust-lib/flowy-database/src/schema.rs index 7397f5b704..6be116e806 100644 --- a/frontend/rust-lib/flowy-database/src/schema.rs +++ b/frontend/rust-lib/flowy-database/src/schema.rs @@ -21,6 +21,17 @@ table! { } } +table! { + grid_meta_rev_table (id) { + id -> Integer, + object_id -> Text, + base_rev_id -> BigInt, + rev_id -> BigInt, + data -> Binary, + state -> Integer, + } +} + table! { grid_rev_table (id) { id -> Integer, @@ -102,6 +113,7 @@ table! { allow_tables_to_appear_in_same_query!( app_table, doc_table, + grid_meta_rev_table, grid_rev_table, kv_table, rev_table, diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index b41539d628..3ccb00466e 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -17,7 +17,8 @@ use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRev use flowy_error::FlowyError; use flowy_folder_data_model::entities::view::ViewDataType; use flowy_folder_data_model::user_default; -use flowy_sync::RevisionWebSocket; +use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; +use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lazy_static::lazy_static; use lib_infra::future::FutureResult; use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc}; @@ -163,7 +164,12 @@ impl FolderManager { let _ = self.persistence.initialize(user_id, &folder_id).await?; let pool = self.persistence.db_pool()?; - let folder_editor = ClientFolderEditor::new(user_id, &folder_id, token, pool, self.web_socket.clone()).await?; + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); + let rev_manager = RevisionManager::new(user_id, folder_id.as_ref(), rev_persistence); + + let folder_editor = + ClientFolderEditor::new(user_id, &folder_id, token, rev_manager, self.web_socket.clone()).await?; *self.folder_editor.write().await = Some(Arc::new(folder_editor)); let _ = self.app_controller.initialize()?; diff --git a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs index 536eef4c9f..203c7c4cec 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -5,14 +5,16 @@ use flowy_collaboration::{ }; use crate::manager::FolderId; +use bytes::Bytes; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::disk::RevisionDiskCache; use flowy_sync::{ - RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, RevisionWebSocket, RevisionWebSocketManager, }; use lib_infra::future::FutureResult; -use lib_ot::core::PlainTextAttributes; +use lib_ot::core::{Delta, PlainTextAttributes}; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -30,19 +32,13 @@ impl ClientFolderEditor { user_id: &str, folder_id: &FolderId, token: &str, - pool: Arc, + mut rev_manager: RevisionManager, web_socket: Arc, ) -> FlowyResult { - let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), pool)); - let mut rev_manager = RevisionManager::new(user_id, folder_id.as_ref(), rev_persistence); let cloud = Arc::new(FolderRevisionCloudService { token: token.to_string(), }); - let folder = Arc::new(RwLock::new( - rev_manager - .load::(cloud) - .await?, - )); + let folder = Arc::new(RwLock::new(rev_manager.load::(cloud).await?)); let rev_manager = Arc::new(rev_manager); let ws_manager = make_folder_ws_manager( user_id, @@ -86,7 +82,7 @@ impl ClientFolderEditor { ); let _ = futures::executor::block_on(async { self.rev_manager - .add_local_revision::(&revision) + .add_local_revision(&revision, Box::new(FolderRevisionCompactor())) .await })?; Ok(()) @@ -128,24 +124,10 @@ impl ClientFolderEditor { } } -struct FolderRevisionCompact(); -impl RevisionCompact for FolderRevisionCompact { - fn compact_revisions(user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { - if revisions.is_empty() { - return Err(FlowyError::internal().context("Can't compact the empty folder's revisions")); - } - - if revisions.len() == 1 { - return Ok(revisions.pop().unwrap()); - } - - let first_revision = revisions.first().unwrap(); - let last_revision = revisions.last().unwrap(); - - let (base_rev_id, rev_id) = first_revision.pair_rev_id(); - let md5 = last_revision.md5.clone(); +struct FolderRevisionCompactor(); +impl RevisionCompactor for FolderRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - let delta_data = delta.to_bytes(); - Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + Ok(delta.to_bytes()) } } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs index 3f499fc45f..20e6d71c66 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -11,6 +11,7 @@ use flowy_folder_data_model::entities::{ view::{RepeatedView, View}, workspace::Workspace, }; +use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; use flowy_sync::{RevisionLoader, RevisionPersistence}; use std::sync::Arc; @@ -87,7 +88,8 @@ impl FolderMigration { return Ok(None); } let pool = self.database.db_pool()?; - let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), pool.clone())); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); let (revisions, _) = RevisionLoader { object_id: folder_id.as_ref().to_owned(), user_id: self.user_id.clone(), diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 83c12b2b78..6c5aa8236a 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -7,6 +7,7 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{Field, RowMeta}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_sync::disk::SQLiteGridRevisionPersistence; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -104,7 +105,9 @@ impl GridManager { fn make_grid_rev_manager(&self, grid_id: &str, pool: Arc) -> FlowyResult { let user_id = self.grid_user.user_id()?; - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, grid_id, pool)); + + let disk_cache = Arc::new(SQLiteGridRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, grid_id, disk_cache)); let rev_manager = RevisionManager::new(&user_id, grid_id, rev_persistence); Ok(rev_manager) } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 9bc7b6da05..4fb93c16b2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -2,6 +2,8 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use crate::services::stringify::stringify_deserialize; +use crate::services::grid_meta_editor::ClientGridBlockMetaEditor; +use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; @@ -10,10 +12,10 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, }; -use flowy_sync::{RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder}; +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_infra::uuid; -use lib_ot::core::PlainTextAttributes; +use lib_ot::core::{Delta, PlainTextAttributes}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; @@ -24,10 +26,8 @@ pub struct ClientGridEditor { user: Arc, grid_meta_pad: Arc>, rev_manager: Arc, + block_meta_manager: Arc, kv_persistence: Arc, - - field_map: DashMap, - cell_map: DashMap, } impl ClientGridEditor { @@ -39,50 +39,22 @@ impl ClientGridEditor { ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); - let grid_pad = rev_manager.load::(cloud).await?; + let grid_pad = rev_manager.load::(cloud).await?; let rev_manager = Arc::new(rev_manager); - let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); - let cell_map = DashMap::new(); + let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new()); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, grid_meta_pad, rev_manager, + block_meta_manager, kv_persistence, - field_map, - cell_map, })) } - pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); - self.create_row(row).await?; - Ok(()) - } - - async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; - // self.cell_map.insert(row.id.clone(), row.clone()); - // let _ = self.kv_persistence.set(row)?; - Ok(()) - } - - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.delete_rows(&ids)?)).await?; - // let _ = self.kv.batch_delete(ids)?; - Ok(()) - } - - // pub async fn update_row(&self, cell: Cell) -> FlowyResult<()> { - // match self.cell_map.get(&cell.id) { - // None => Err(FlowyError::internal().context(format!("Can't find cell with id: {}", cell.id))), - // Some(raw_cell) => {} - // } - // } - pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; Ok(()) @@ -90,76 +62,38 @@ impl ClientGridEditor { pub async fn delete_field(&mut self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; - // let _ = self.kv.remove(field_id)?; Ok(()) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { - let ids = row_orders - .items - .into_iter() - .map(|row_order| row_order.row_id) - .collect::>(); - let row_metas: Vec = self.kv_persistence.batch_get(ids)?; - - let make_cell = |field_id: String, raw_cell: CellMeta| { - let some_field = self.field_map.get(&field_id); - if some_field.is_none() { - tracing::error!("Can't find the field with {}", field_id); - return None; - } - self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - - let field = some_field.unwrap(); - match stringify_deserialize(raw_cell.data, field.value()) { - Ok(content) => { - let cell = Cell { - id: raw_cell.id, - field_id: field_id.clone(), - content, - }; - Some((field_id, cell)) - } - Err(_) => None, - } - }; - - let rows = row_metas - .into_par_iter() - .map(|row_meta| { - let mut row = Row { - id: row_meta.id.clone(), - cell_by_field_id: Default::default(), - height: row_meta.height, - }; - row.cell_by_field_id = row_meta - .cell_by_field_id - .into_par_iter() - .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - .collect::>(); - row - }) - .collect::>(); - - Ok(rows.into()) + pub async fn create_empty_row(&self) -> FlowyResult<()> { + // let _ = self.modify(|grid| { + // + // + // grid.blocks + // + // }).await?; + todo!() } - pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { - let fields = field_orders - .iter() - .flat_map(|field_order| match self.field_map.get(&field_order.field_id) { - None => { - tracing::error!("Can't find the field with {}", field_order.field_id); - None - } - Some(field) => Some(field.value().clone()), - }) - .collect::>(); - Ok(fields.into()) + async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + todo!() + } + + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + todo!() + } + + pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { + todo!() } pub async fn grid_data(&self) -> Grid { - self.grid_meta_pad.read().await.grid_data() + todo!() + } + + pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { + let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; + Ok(fields) } pub async fn delta_str(&self) -> String { @@ -195,7 +129,7 @@ impl ClientGridEditor { ); let _ = self .rev_manager - .add_local_revision::(&revision) + .add_local_revision(&revision, Box::new(GridRevisionCompactor())) .await?; Ok(()) } @@ -241,24 +175,73 @@ impl RevisionCloudService for GridRevisionCloudService { } } -struct GridRevisionCompact(); -impl RevisionCompact for GridRevisionCompact { - fn compact_revisions(user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { - if revisions.is_empty() { - return Err(FlowyError::internal().context("Can't compact the empty folder's revisions")); - } - - if revisions.len() == 1 { - return Ok(revisions.pop().unwrap()); - } - - let first_revision = revisions.first().unwrap(); - let last_revision = revisions.last().unwrap(); - - let (base_rev_id, rev_id) = first_revision.pair_rev_id(); - let md5 = last_revision.md5.clone(); +struct GridRevisionCompactor(); +impl RevisionCompactor for GridRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - let delta_data = delta.to_bytes(); - Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + Ok(delta.to_bytes()) + } +} + +struct GridBlockMetaEditorManager { + editor_map: DashMap>, +} + +impl GridBlockMetaEditorManager { + fn new() -> Self { + Self { + editor_map: DashMap::new(), + } + } + + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + // let ids = row_orders + // .items + // .into_iter() + // .map(|row_order| row_order.row_id) + // .collect::>(); + // let row_metas: Vec = self.kv_persistence.batch_get(ids)?; + // + // let make_cell = |field_id: String, raw_cell: CellMeta| { + // let some_field = self.field_map.get(&field_id); + // if some_field.is_none() { + // tracing::error!("Can't find the field with {}", field_id); + // return None; + // } + // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); + // + // let field = some_field.unwrap(); + // match stringify_deserialize(raw_cell.data, field.value()) { + // Ok(content) => { + // let cell = Cell { + // id: raw_cell.id, + // field_id: field_id.clone(), + // content, + // }; + // Some((field_id, cell)) + // } + // Err(_) => None, + // } + // }; + // + // let rows = row_metas + // .into_par_iter() + // .map(|row_meta| { + // let mut row = Row { + // id: row_meta.id.clone(), + // cell_by_field_id: Default::default(), + // height: row_meta.height, + // }; + // row.cell_by_field_id = row_meta + // .cell_by_field_id + // .into_par_iter() + // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) + // .collect::>(); + // row + // }) + // .collect::>(); + // + // Ok(rows.into()) + todo!() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs new file mode 100644 index 0000000000..3e3e5e82d3 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -0,0 +1,125 @@ +use bytes::Bytes; +use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; +use flowy_collaboration::entities::revision::Revision; +use flowy_collaboration::util::make_delta_from_revisions; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::RowMeta; +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; +use lib_infra::future::FutureResult; +use lib_infra::uuid; +use lib_ot::core::PlainTextAttributes; +use std::sync::Arc; +use tokio::sync::RwLock; + +pub struct ClientGridBlockMetaEditor { + user_id: String, + block_id: String, + meta_pad: Arc>, + rev_manager: Arc, +} + +impl ClientGridBlockMetaEditor { + pub async fn new( + user_id: &str, + token: &str, + block_id: String, + mut rev_manager: RevisionManager, + ) -> FlowyResult { + let cloud = Arc::new(GridBlockMetaRevisionCloudService { + token: token.to_owned(), + }); + let block_meta_pad = rev_manager.load::(cloud).await?; + let meta_pad = Arc::new(RwLock::new(block_meta_pad)); + let rev_manager = Arc::new(rev_manager); + let user_id = user_id.to_owned(); + Ok(Self { + user_id, + block_id, + meta_pad, + rev_manager, + }) + } + + pub async fn create_empty_row(&self) -> FlowyResult<()> { + let row = RowMeta::new(&uuid(), &self.block_id, vec![]); + self.create_row(row).await?; + Ok(()) + } + + async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + // let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; + // self.cell_map.insert(row.id.clone(), row.clone()); + // let _ = self.kv_persistence.set(row)?; + Ok(()) + } + + pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { + // let _ = self.modify(|grid| Ok(grid.delete_rows(&ids)?)).await?; + // let _ = self.kv.batch_delete(ids)?; + Ok(()) + } + + async fn modify(&self, f: F) -> FlowyResult<()> + where + F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, + { + let mut write_guard = self.meta_pad.write().await; + match f(&mut *write_guard)? { + None => {} + Some(change) => { + let _ = self.apply_change(change).await?; + } + } + Ok(()) + } + + async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> { + let GridBlockMetaChange { delta, md5 } = change; + let user_id = self.user_id.clone(); + let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); + let delta_data = delta.to_bytes(); + let revision = Revision::new( + &self.rev_manager.object_id, + base_rev_id, + rev_id, + delta_data, + &user_id, + md5, + ); + let _ = self + .rev_manager + .add_local_revision(&revision, Box::new(GridBlockMetaRevisionCompactor())) + .await?; + Ok(()) + } +} + +struct GridBlockMetaRevisionCloudService { + #[allow(dead_code)] + token: String, +} + +impl RevisionCloudService for GridBlockMetaRevisionCloudService { + #[tracing::instrument(level = "trace", skip(self))] + fn fetch_object(&self, _user_id: &str, _object_id: &str) -> FutureResult, FlowyError> { + FutureResult::new(async move { Ok(vec![]) }) + } +} + +struct GridBlockMetaPadBuilder(); +impl RevisionObjectBuilder for GridBlockMetaPadBuilder { + type Output = GridBlockMetaPad; + + fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { + let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?; + Ok(pad) + } +} + +struct GridBlockMetaRevisionCompactor(); +impl RevisionCompactor for GridBlockMetaRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { + let delta = make_delta_from_revisions::(revisions)?; + Ok(delta.to_bytes()) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index f1e1086589..226426aeb7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -3,5 +3,6 @@ mod util; pub mod cell_data; pub mod grid_builder; pub mod grid_editor; +pub mod grid_meta_editor; pub mod kv_persistence; pub mod stringify; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 5550395229..6fea7bbe73 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -66,10 +66,10 @@ fn make_view_data_processor( ) -> ViewDataProcessorMap { let mut map: HashMap> = HashMap::new(); - let block_data_impl = BlockManagerViewDataImpl(text_block_manager); + let block_data_impl = TextBlockViewDataProcessor(text_block_manager); map.insert(block_data_impl.data_type(), Arc::new(block_data_impl)); - let grid_data_impl = GridManagerViewDataImpl(grid_manager); + let grid_data_impl = GridViewDataProcessor(grid_manager); map.insert(grid_data_impl.data_type(), Arc::new(grid_data_impl)); Arc::new(map) @@ -133,8 +133,8 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl { } } -struct BlockManagerViewDataImpl(Arc); -impl ViewDataProcessor for BlockManagerViewDataImpl { +struct TextBlockViewDataProcessor(Arc); +impl ViewDataProcessor for TextBlockViewDataProcessor { fn initialize(&self) -> FutureResult<(), FlowyError> { let manager = self.0.clone(); FutureResult::new(async move { manager.init() }) @@ -186,8 +186,8 @@ impl ViewDataProcessor for BlockManagerViewDataImpl { } } -struct GridManagerViewDataImpl(Arc); -impl ViewDataProcessor for GridManagerViewDataImpl { +struct GridViewDataProcessor(Arc); +impl ViewDataProcessor for GridViewDataProcessor { fn initialize(&self) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs new file mode 100644 index 0000000000..ba4a0950af --- /dev/null +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs @@ -0,0 +1,235 @@ +use crate::cache::disk::RevisionDiskCache; +use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use crate::memory::RevisionMemoryCacheDelegate; +use bytes::Bytes; +use diesel::{sql_types::Integer, update, SqliteConnection}; +use flowy_collaboration::{ + entities::revision::{RevId, RevType, Revision, RevisionRange}, + util::md5, +}; +use flowy_database::{ + impl_sql_integer_expression, insert_or_ignore_into, + prelude::*, + schema::{grid_meta_rev_table, grid_meta_rev_table::dsl}, + ConnectionPool, +}; +use flowy_error::{internal_error, FlowyError, FlowyResult}; +use std::sync::Arc; + +pub struct SQLiteGridBlockMetaRevisionPersistence { + user_id: String, + pub(crate) pool: Arc, +} + +impl RevisionDiskCache for SQLiteGridBlockMetaRevisionPersistence { + type Error = FlowyError; + + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let _ = GridMetaRevisionSql::create(revision_records, &*conn)?; + Ok(()) + } + + fn read_revision_records( + &self, + object_id: &str, + rev_ids: Option>, + ) -> Result, Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let records = GridMetaRevisionSql::read(&self.user_id, object_id, rev_ids, &*conn)?; + Ok(records) + } + + fn read_revision_records_with_range( + &self, + object_id: &str, + range: &RevisionRange, + ) -> Result, Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let revisions = GridMetaRevisionSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; + Ok(revisions) + } + + fn update_revision_record(&self, changesets: Vec) -> FlowyResult<()> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = conn.immediate_transaction::<_, FlowyError, _>(|| { + for changeset in changesets { + let _ = GridMetaRevisionSql::update(changeset, conn)?; + } + Ok(()) + })?; + Ok(()) + } + + fn delete_revision_records(&self, object_id: &str, rev_ids: Option>) -> Result<(), Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = GridMetaRevisionSql::delete(object_id, rev_ids, conn)?; + Ok(()) + } + + fn delete_and_insert_records( + &self, + object_id: &str, + deleted_rev_ids: Option>, + inserted_records: Vec, + ) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + conn.immediate_transaction::<_, FlowyError, _>(|| { + let _ = GridMetaRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; + let _ = GridMetaRevisionSql::create(inserted_records, &*conn)?; + Ok(()) + }) + } +} + +impl SQLiteGridBlockMetaRevisionPersistence { + pub fn new(user_id: &str, pool: Arc) -> Self { + Self { + user_id: user_id.to_owned(), + pool, + } + } +} + +struct GridMetaRevisionSql(); +impl GridMetaRevisionSql { + fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { + // Batch insert: https://diesel.rs/guides/all-about-inserts.html + + let records = revision_records + .into_iter() + .map(|record| { + tracing::trace!( + "[GridMetaRevisionSql] create revision: {}:{:?}", + record.revision.object_id, + record.revision.rev_id + ); + let rev_state: GridMetaRevisionState = record.state.into(); + ( + dsl::object_id.eq(record.revision.object_id), + dsl::base_rev_id.eq(record.revision.base_rev_id), + dsl::rev_id.eq(record.revision.rev_id), + dsl::data.eq(record.revision.delta_data), + dsl::state.eq(rev_state), + ) + }) + .collect::>(); + + let _ = insert_or_ignore_into(dsl::grid_meta_rev_table) + .values(&records) + .execute(conn)?; + Ok(()) + } + + fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + let state: GridMetaRevisionState = changeset.state.clone().into(); + let filter = dsl::grid_meta_rev_table + .filter(dsl::rev_id.eq(changeset.rev_id.as_ref())) + .filter(dsl::object_id.eq(changeset.object_id)); + let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?; + tracing::debug!( + "[GridMetaRevisionSql] update revision:{} state:to {:?}", + changeset.rev_id, + changeset.state + ); + Ok(()) + } + + fn read( + user_id: &str, + object_id: &str, + rev_ids: Option>, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let mut sql = dsl::grid_meta_rev_table + .filter(dsl::object_id.eq(object_id)) + .into_boxed(); + if let Some(rev_ids) = rev_ids { + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + let rows = sql.order(dsl::rev_id.asc()).load::(conn)?; + let records = rows + .into_iter() + .map(|row| mk_revision_record_from_table(user_id, row)) + .collect::>(); + + Ok(records) + } + + fn read_with_range( + user_id: &str, + object_id: &str, + range: RevisionRange, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let rev_tables = dsl::grid_meta_rev_table + .filter(dsl::rev_id.ge(range.start)) + .filter(dsl::rev_id.le(range.end)) + .filter(dsl::object_id.eq(object_id)) + .order(dsl::rev_id.asc()) + .load::(conn)?; + + let revisions = rev_tables + .into_iter() + .map(|table| mk_revision_record_from_table(user_id, table)) + .collect::>(); + Ok(revisions) + } + + fn delete(object_id: &str, rev_ids: Option>, conn: &SqliteConnection) -> Result<(), FlowyError> { + let mut sql = diesel::delete(dsl::grid_meta_rev_table).into_boxed(); + sql = sql.filter(dsl::object_id.eq(object_id)); + + if let Some(rev_ids) = rev_ids { + tracing::trace!("[GridMetaRevisionSql] Delete revision: {}:{:?}", object_id, rev_ids); + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + + let affected_row = sql.execute(conn)?; + tracing::trace!("[GridMetaRevisionSql] Delete {} rows", affected_row); + Ok(()) + } +} + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] +#[table_name = "grid_meta_rev_table"] +struct GridMetaRevisionTable { + id: i32, + object_id: String, + base_rev_id: i64, + rev_id: i64, + data: Vec, + state: GridMetaRevisionState, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] +#[repr(i32)] +#[sql_type = "Integer"] +pub enum GridMetaRevisionState { + Sync = 0, + Ack = 1, +} +impl_sql_integer_expression!(GridMetaRevisionState); +impl_rev_state_map!(GridMetaRevisionState); +impl std::default::Default for GridMetaRevisionState { + fn default() -> Self { + GridMetaRevisionState::Sync + } +} + +fn mk_revision_record_from_table(user_id: &str, table: GridMetaRevisionTable) -> RevisionRecord { + let md5 = md5(&table.data); + let revision = Revision::new( + &table.object_id, + table.base_rev_id, + table.rev_id, + Bytes::from(table.data), + user_id, + md5, + ); + RevisionRecord { + revision, + state: table.state.into(), + write_to_disk: false, + } +} diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs index 6053b17133..385bc812c7 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs @@ -1,5 +1,6 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use crate::memory::RevisionMemoryCacheDelegate; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ @@ -23,12 +24,9 @@ pub struct SQLiteGridRevisionPersistence { impl RevisionDiskCache for SQLiteGridRevisionPersistence { type Error = FlowyError; - fn create_revision_records( - &self, - revision_records: Vec, - conn: &SqliteConnection, - ) -> Result<(), Self::Error> { - let _ = GridRevisionSql::create(revision_records, conn)?; + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let _ = GridRevisionSql::create(revision_records, &*conn)?; Ok(()) } @@ -78,14 +76,14 @@ impl RevisionDiskCache for SQLiteGridRevisionPersistence { let conn = self.pool.get().map_err(internal_error)?; conn.immediate_transaction::<_, FlowyError, _>(|| { let _ = GridRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; - let _ = self.create_revision_records(inserted_records, &*conn)?; + let _ = GridRevisionSql::create(inserted_records, &*conn)?; Ok(()) }) } } impl SQLiteGridRevisionPersistence { - pub(crate) fn new(user_id: &str, pool: Arc) -> Self { + pub fn new(user_id: &str, pool: Arc) -> Self { Self { user_id: user_id.to_owned(), pool, @@ -193,13 +191,13 @@ impl GridRevisionSql { #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[table_name = "grid_rev_table"] -pub(crate) struct GridRevisionTable { +struct GridRevisionTable { id: i32, - pub(crate) object_id: String, - pub(crate) base_rev_id: i64, - pub(crate) rev_id: i64, - pub(crate) data: Vec, - pub(crate) state: GridRevisionState, + object_id: String, + base_rev_id: i64, + rev_id: i64, + data: Vec, + state: GridRevisionState, } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] @@ -209,6 +207,8 @@ pub enum GridRevisionState { Sync = 0, Ack = 1, } +impl_sql_integer_expression!(GridRevisionState); +impl_rev_state_map!(GridRevisionState); impl std::default::Default for GridRevisionState { fn default() -> Self { @@ -216,44 +216,6 @@ impl std::default::Default for GridRevisionState { } } -impl std::convert::From for GridRevisionState { - fn from(value: i32) -> Self { - match value { - 0 => GridRevisionState::Sync, - 1 => GridRevisionState::Ack, - o => { - tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); - GridRevisionState::Sync - } - } - } -} - -impl GridRevisionState { - pub fn value(&self) -> i32 { - *self as i32 - } -} -impl_sql_integer_expression!(GridRevisionState); - -impl std::convert::From for RevisionState { - fn from(s: GridRevisionState) -> Self { - match s { - GridRevisionState::Sync => RevisionState::Sync, - GridRevisionState::Ack => RevisionState::Ack, - } - } -} - -impl std::convert::From for GridRevisionState { - fn from(s: RevisionState) -> Self { - match s { - RevisionState::Sync => GridRevisionState::Sync, - RevisionState::Ack => GridRevisionState::Ack, - } - } -} - fn mk_revision_record_from_table(user_id: &str, table: GridRevisionTable) -> RevisionRecord { let md5 = md5(&table.data); let revision = Revision::new( diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index 4fcad2d2ec..e261f8d7ec 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -1,11 +1,14 @@ mod folder_rev_impl; +mod grid_meta_rev_impl; mod grid_rev_impl; mod text_rev_impl; pub use folder_rev_impl::*; +pub use grid_meta_rev_impl::*; pub use grid_rev_impl::*; pub use text_rev_impl::*; +use crate::memory::RevisionMemoryCacheDelegate; use diesel::SqliteConnection; use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; @@ -13,11 +16,7 @@ use std::fmt::Debug; pub trait RevisionDiskCache: Sync + Send { type Error: Debug; - fn create_revision_records( - &self, - revision_records: Vec, - conn: &SqliteConnection, - ) -> Result<(), Self::Error>; + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error>; // Read all the records if the rev_ids is None fn read_revision_records( diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs index 7659ad33dc..0d780f824a 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs @@ -1,5 +1,6 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use crate::memory::RevisionMemoryCacheDelegate; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ @@ -23,12 +24,9 @@ pub struct SQLiteTextBlockRevisionPersistence { impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { type Error = FlowyError; - fn create_revision_records( - &self, - revision_records: Vec, - conn: &SqliteConnection, - ) -> Result<(), Self::Error> { - let _ = TextRevisionSql::create(revision_records, conn)?; + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let _ = TextRevisionSql::create(revision_records, &*conn)?; Ok(()) } @@ -78,14 +76,14 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { let conn = self.pool.get().map_err(internal_error)?; conn.immediate_transaction::<_, FlowyError, _>(|| { let _ = TextRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; - let _ = self.create_revision_records(inserted_records, &*conn)?; + let _ = TextRevisionSql::create(inserted_records, &*conn)?; Ok(()) }) } } impl SQLiteTextBlockRevisionPersistence { - pub(crate) fn new(user_id: &str, pool: Arc) -> Self { + pub fn new(user_id: &str, pool: Arc) -> Self { Self { user_id: user_id.to_owned(), pool, @@ -210,6 +208,8 @@ enum TextRevisionState { Sync = 0, Ack = 1, } +impl_sql_integer_expression!(TextRevisionState); +impl_rev_state_map!(TextRevisionState); impl std::default::Default for TextRevisionState { fn default() -> Self { @@ -217,44 +217,6 @@ impl std::default::Default for TextRevisionState { } } -impl std::convert::From for TextRevisionState { - fn from(value: i32) -> Self { - match value { - 0 => TextRevisionState::Sync, - 1 => TextRevisionState::Ack, - o => { - tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); - TextRevisionState::Sync - } - } - } -} - -impl TextRevisionState { - pub fn value(&self) -> i32 { - *self as i32 - } -} -impl_sql_integer_expression!(TextRevisionState); - -impl std::convert::From for RevisionState { - fn from(s: TextRevisionState) -> Self { - match s { - TextRevisionState::Sync => RevisionState::Sync, - TextRevisionState::Ack => RevisionState::Ack, - } - } -} - -impl std::convert::From for TextRevisionState { - fn from(s: RevisionState) -> Self { - match s { - RevisionState::Sync => TextRevisionState::Sync, - RevisionState::Ack => TextRevisionState::Ack, - } - } -} - fn mk_revision_record_from_table(user_id: &str, table: RevisionTable) -> RevisionRecord { let md5 = md5(&table.data); let revision = Revision::new( @@ -279,6 +241,7 @@ pub enum RevTableType { Local = 0, Remote = 1, } +impl_sql_integer_expression!(RevTableType); impl std::default::Default for RevTableType { fn default() -> Self { @@ -298,12 +261,6 @@ impl std::convert::From for RevTableType { } } } -impl RevTableType { - pub fn value(&self) -> i32 { - *self as i32 - } -} -impl_sql_integer_expression!(RevTableType); impl std::convert::From for RevTableType { fn from(ty: RevType) -> Self { diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index ab5d7858b3..ae26bbf68c 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -1,11 +1,13 @@ use crate::disk::RevisionState; use crate::{RevisionPersistence, WSDataProviderDataSource}; +use bytes::Bytes; use flowy_collaboration::{ entities::revision::{RepeatedRevision, Revision, RevisionRange}, util::{pair_rev_id_from_revisions, RevIdCounter}, }; use flowy_error::{FlowyError, FlowyResult}; use lib_infra::future::FutureResult; +use lib_ot::core::{Attributes, Delta}; use std::sync::Arc; pub trait RevisionCloudService: Send + Sync { @@ -17,8 +19,26 @@ pub trait RevisionObjectBuilder: Send + Sync { fn build_object(object_id: &str, revisions: Vec) -> FlowyResult; } -pub trait RevisionCompact: Send + Sync { - fn compact_revisions(user_id: &str, object_id: &str, revisions: Vec) -> FlowyResult; +pub trait RevisionCompactor: Send + Sync { + fn compact(&self, user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { + if revisions.is_empty() { + return Err(FlowyError::internal().context("Can't compact the empty folder's revisions")); + } + + if revisions.len() == 1 { + return Ok(revisions.pop().unwrap()); + } + + let first_revision = revisions.first().unwrap(); + let last_revision = revisions.last().unwrap(); + + let (base_rev_id, rev_id) = first_revision.pair_rev_id(); + let md5 = last_revision.md5.clone(); + let delta_data = self.bytes_from_revisions(revisions)?; + Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + } + + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult; } pub struct RevisionManager { @@ -48,10 +68,9 @@ impl RevisionManager { } } - pub async fn load(&mut self, cloud: Arc) -> FlowyResult + pub async fn load(&mut self, cloud: Arc) -> FlowyResult where B: RevisionObjectBuilder, - C: RevisionCompact, { let (revisions, rev_id) = RevisionLoader { object_id: self.object_id.clone(), @@ -84,15 +103,16 @@ impl RevisionManager { Ok(()) } - #[tracing::instrument(level = "debug", skip(self, revision))] - pub async fn add_local_revision(&self, revision: &Revision) -> Result<(), FlowyError> - where - C: RevisionCompact, - { + #[tracing::instrument(level = "debug", skip_all, err)] + pub async fn add_local_revision<'a>( + &'a self, + revision: &Revision, + compactor: Box, + ) -> Result<(), FlowyError> { if revision.delta_data.is_empty() { return Err(FlowyError::internal().context("Delta data should be empty")); } - let rev_id = self.rev_persistence.add_sync_revision::(revision).await?; + let rev_id = self.rev_persistence.add_sync_revision(revision, compactor).await?; self.rev_id_counter.set(rev_id); Ok(()) } diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs index d6b129170f..8a1d9647c4 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs @@ -1,9 +1,10 @@ use crate::cache::{ disk::{RevisionChangeset, RevisionDiskCache, SQLiteTextBlockRevisionPersistence}, - memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, + memory::RevisionMemoryCacheDelegate, }; use crate::disk::{RevisionRecord, RevisionState}; -use crate::RevisionCompact; +use crate::memory::RevisionMemoryCache; +use crate::RevisionCompactor; use flowy_collaboration::entities::revision::{Revision, RevisionRange}; use flowy_database::ConnectionPool; use flowy_error::{internal_error, FlowyError, FlowyResult}; @@ -21,13 +22,17 @@ pub struct RevisionPersistence { memory_cache: Arc, sync_seq: RwLock, } + impl RevisionPersistence { - pub fn new(user_id: &str, object_id: &str, pool: Arc) -> RevisionPersistence { - let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); - let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone()))); + pub fn new( + user_id: &str, + object_id: &str, + disk_cache: Arc>, + ) -> RevisionPersistence { let object_id = object_id.to_owned(); let user_id = user_id.to_owned(); let sync_seq = RwLock::new(RevisionSyncSequence::new()); + let memory_cache = Arc::new(RevisionMemoryCache::new(&object_id, Arc::new(disk_cache.clone()))); Self { user_id, object_id, @@ -54,11 +59,12 @@ impl RevisionPersistence { } /// Save the revision to disk and append it to the end of the sync sequence. - #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)] - pub(crate) async fn add_sync_revision(&self, revision: &Revision) -> FlowyResult - where - C: RevisionCompact, - { + #[tracing::instrument(level = "trace", skip_all, fields(rev_id, compact_range, object_id=%self.object_id), err)] + pub(crate) async fn add_sync_revision<'a>( + &'a self, + revision: &'a Revision, + compactor: Box, + ) -> FlowyResult { let result = self.sync_seq.read().await.compact(); match result { None => { @@ -78,7 +84,7 @@ impl RevisionPersistence { revisions.push(revision.clone()); // compact multiple revisions into one - let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?; + let compact_revision = compactor.compact(&self.user_id, &self.object_id, revisions)?; let rev_id = compact_revision.rev_id; tracing::Span::current().record("rev_id", &rev_id); @@ -215,17 +221,15 @@ pub fn mk_revision_disk_cache( Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)) } -impl RevisionMemoryCacheDelegate for Arc { - #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)] +impl RevisionMemoryCacheDelegate for Arc> { fn checkpoint_tick(&self, mut records: Vec) -> FlowyResult<()> { - let conn = &*self.pool.get().map_err(internal_error)?; records.retain(|record| record.write_to_disk); if !records.is_empty() { tracing::Span::current().record( "checkpoint_result", &format!("{} records were saved", records.len()).as_str(), ); - let _ = self.create_revision_records(records, conn)?; + let _ = self.create_revision_records(records)?; } Ok(()) } diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 54f4b67967..0ca0d5ee03 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,28 +1,28 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowMetaChangeset, RowOrder}; +use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset, RowOrder}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; use std::sync::Arc; -pub type BlockMetaDelta = PlainTextDelta; -pub type BlockDeltaBuilder = PlainTextDeltaBuilder; +pub type GridBlockMetaDelta = PlainTextDelta; +pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct BlockMetaPad { +pub struct GridBlockMetaPad { block_id: String, rows: Vec>, #[serde(skip)] - pub(crate) delta: BlockMetaDelta, + pub(crate) delta: GridBlockMetaDelta, } -impl BlockMetaPad { - pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult { +impl GridBlockMetaPad { + pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_meta: BlockMeta = serde_json::from_str(&s).map_err(|e| { + let block_meta: GridBlockMeta = serde_json::from_str(&s).map_err(|e| { CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) })?; let block_id = block_meta.block_id; @@ -31,25 +31,25 @@ impl BlockMetaPad { } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { - let block_delta: BlockMetaDelta = make_delta_from_revisions::(revisions)?; + let block_delta: GridBlockMetaDelta = make_delta_from_revisions::(revisions)?; Self::from_delta(block_delta) } - pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { + pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { self.modify(|rows| { rows.push(Arc::new(row)); Ok(Some(())) }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify(|rows| { rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } - pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { let mut is_changed = None; @@ -74,7 +74,7 @@ impl BlockMetaPad { }) } - pub fn modify(&mut self, f: F) -> CollaborateResult> + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { @@ -88,14 +88,14 @@ impl BlockMetaPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(BlockMetaChange { delta, md5: self.md5() })) + Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } } } } } - fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut RowMeta) -> CollaborateResult>, { @@ -123,39 +123,39 @@ impl BlockMetaPad { } } -fn json_from_grid(block_meta: &Arc) -> CollaborateResult { +fn json_from_grid(block_meta: &Arc) -> CollaborateResult { let json = serde_json::to_string(block_meta) .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; Ok(json) } -pub struct BlockMetaChange { - pub delta: BlockMetaDelta, +pub struct GridBlockMetaChange { + pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_block_meta_delta(block_meta: &BlockMeta) -> BlockMetaDelta { +pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta { let json = serde_json::to_string(&block_meta).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, block_meta: &BlockMeta) -> RepeatedRevision { +pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision { let delta = make_block_meta_delta(block_meta); let bytes = delta.to_bytes(); let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); revision.into() } -impl std::default::Default for BlockMetaPad { +impl std::default::Default for GridBlockMetaPad { fn default() -> Self { - let block_meta = BlockMeta { + let block_meta = GridBlockMeta { block_id: uuid(), rows: vec![], }; let delta = make_block_meta_delta(&block_meta); - BlockMetaPad { + GridBlockMetaPad { block_id: block_meta.block_id, rows: block_meta.rows.into_iter().map(Arc::new).collect::>(), delta, @@ -165,7 +165,7 @@ impl std::default::Default for BlockMetaPad { #[cfg(test)] mod tests { - use crate::client_grid::{BlockMetaDelta, BlockMetaPad}; + use crate::client_grid::{GridBlockMetaDelta, GridMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; use std::str::FromStr; @@ -241,8 +241,8 @@ mod tests { ); } - fn test_pad() -> BlockMetaPad { - let delta = BlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - BlockMetaPad::from_delta(delta).unwrap() + fn test_pad() -> GridMetaPad { + let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); + GridMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index f61cd484fc..6e04107e44 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,9 +1,13 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, GridMeta, RowMeta, RowOrder}; +use flowy_grid_data_model::entities::{ + Field, FieldChangeset, FieldOrder, Grid, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, + RepeatedFieldOrder, RowMeta, RowOrder, +}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use std::collections::HashMap; use std::sync::Arc; pub type GridDelta = PlainTextDelta; @@ -31,13 +35,6 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { - self.modify_grid(|grid| { - // grid.rows.push(row); - Ok(Some(())) - }) - } - pub fn create_field(&mut self, field: Field) -> CollaborateResult> { self.modify_grid(|grid| { grid.fields.push(field); @@ -45,13 +42,6 @@ impl GridMetaPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { - self.modify_grid(|grid| { - // grid.rows.retain(|row| !row_ids.contains(&row.id)); - Ok(Some(())) - }) - } - pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { None => Ok(None), @@ -62,30 +52,93 @@ impl GridMetaPad { }) } - pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) - } - - pub fn grid_data(&self) -> Grid { - let field_orders = self + pub fn get_fields(&self, field_orders: RepeatedFieldOrder) -> CollaborateResult { + let field_by_field_id = self .grid_meta .fields .iter() - .map(FieldOrder::from) - .collect::>(); + .map(|field| (&field.id, field)) + .collect::>(); - // let row_orders = self - // .grid_meta - // .rows - // .iter() - // .map(RowOrder::from) - // .collect::>(); + let fields = field_orders + .iter() + .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { + None => { + tracing::error!("Can't find the field with {}", field_order.field_id); + None + } + Some(field) => Some((*field).clone()), + }) + .collect::>(); + Ok(fields.into()) + } - Grid { - id: "".to_string(), - field_orders, - row_orders: vec![], - } + pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult> { + let field_id = change.field_id.clone(); + self.modify_field(&field_id, |field| { + let mut is_changed = None; + if let Some(name) = change.name { + field.name = name; + is_changed = Some(()) + } + + if let Some(desc) = change.desc { + field.desc = desc; + is_changed = Some(()) + } + + if let Some(field_type) = change.field_type { + field.field_type = field_type; + is_changed = Some(()) + } + + if let Some(frozen) = change.frozen { + field.frozen = frozen; + is_changed = Some(()) + } + + if let Some(visibility) = change.visibility { + field.visibility = visibility; + is_changed = Some(()) + } + + if let Some(width) = change.width { + field.width = width; + is_changed = Some(()) + } + + if let Some(type_options) = change.type_options { + field.type_options = type_options; + is_changed = Some(()) + } + + Ok(is_changed) + }) + } + + pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { + self.modify_grid(|grid| { + grid.blocks.push(block); + Ok(Some(())) + }) + } + + pub fn update_block(&mut self, change: GridBlockChangeset) -> CollaborateResult> { + let block_id = change.block_id.clone(); + self.modify_block(&block_id, |block| { + let mut is_changed = None; + + if let Some(row_count) = change.row_count { + block.row_count = row_count; + is_changed = Some(()); + } + + Ok(is_changed) + }) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) } pub fn delta_str(&self) -> String { @@ -96,7 +149,7 @@ impl GridMetaPad { &self.grid_meta.fields } - pub fn modify_grid(&mut self, f: F) -> CollaborateResult> + fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut GridMeta) -> CollaborateResult>, { @@ -116,6 +169,32 @@ impl GridMetaPad { } } } + + pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> + where + F: FnOnce(&mut GridBlock) -> CollaborateResult>, + { + self.modify_grid(|grid| match grid.blocks.iter().position(|block| block.id == block_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); + Ok(None) + } + Some(index) => f(&mut grid.blocks[index]), + }) + } + + pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> + where + F: FnOnce(&mut Field) -> CollaborateResult>, + { + self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any field with id: {}", field_id); + Ok(None) + } + Some(index) => f(&mut grid.fields[index]), + }) + } } fn json_from_grid(grid: &Arc) -> CollaborateResult { diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index e5f5c189cc..00c3981d79 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -2,9 +2,6 @@ use crate::entities::{Field, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; -pub const DEFAULT_ROW_HEIGHT: i32 = 36; -pub const DEFAULT_FIELD_WIDTH: i32 = 150; - #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index e8483dcb02..f6691456c8 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -15,11 +15,11 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct Block { +pub struct GridBlock { #[pb(index = 1)] pub id: String, @@ -30,8 +30,14 @@ pub struct Block { pub row_count: i32, } +pub struct GridBlockChangeset { + pub block_id: String, + pub start_row_index: Option, + pub row_count: Option, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct BlockMeta { +pub struct GridBlockMeta { #[pb(index = 1)] pub block_id: String, @@ -81,6 +87,33 @@ impl Field { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldChangeset { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2, one_of)] + pub name: Option, + + #[pb(index = 3, one_of)] + pub desc: Option, + + #[pb(index = 4, one_of)] + pub field_type: Option, + + #[pb(index = 5, one_of)] + pub frozen: Option, + + #[pb(index = 6, one_of)] + pub visibility: Option, + + #[pb(index = 7, one_of)] + pub width: Option, + + #[pb(index = 8, one_of)] + pub type_options: Option, +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedField { #[pb(index = 1)] @@ -191,7 +224,7 @@ pub struct RowMeta { } impl RowMeta { - pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { + pub fn new(id: &str, block_id: &str, cells: Vec) -> Self { let cell_by_field_id = cells .into_iter() .map(|cell| (cell.id.clone(), cell)) @@ -199,7 +232,7 @@ impl RowMeta { Self { id: id.to_owned(), - block_id: grid_id.to_owned(), + block_id: block_id.to_owned(), cell_by_field_id, height: DEFAULT_ROW_HEIGHT, visibility: true, diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4107603b67..4ef31470a8 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,10 +96,10 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .Block blocks = 3; + // repeated .GridBlock blocks = 3; - pub fn get_blocks(&self) -> &[Block] { + pub fn get_blocks(&self) -> &[GridBlock] { &self.blocks } pub fn clear_blocks(&mut self) { @@ -107,17 +107,17 @@ impl GridMeta { } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { self.blocks = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.blocks } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -240,7 +240,7 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "blocks", |m: &GridMeta| { &m.blocks }, |m: &mut GridMeta| { &mut m.blocks }, @@ -281,7 +281,7 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta { } #[derive(PartialEq,Clone,Default)] -pub struct Block { +pub struct GridBlock { // message fields pub id: ::std::string::String, pub start_row_index: i32, @@ -291,14 +291,14 @@ pub struct Block { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a Block { - fn default() -> &'a Block { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlock { + fn default() -> &'a GridBlock { + ::default_instance() } } -impl Block { - pub fn new() -> Block { +impl GridBlock { + pub fn new() -> GridBlock { ::std::default::Default::default() } @@ -359,7 +359,7 @@ impl Block { } } -impl ::protobuf::Message for Block { +impl ::protobuf::Message for GridBlock { fn is_initialized(&self) -> bool { true } @@ -451,8 +451,8 @@ impl ::protobuf::Message for Block { Self::descriptor_static() } - fn new() -> Block { - Block::new() + fn new() -> GridBlock { + GridBlock::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -461,34 +461,34 @@ impl ::protobuf::Message for Block { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &Block| { &m.id }, - |m: &mut Block| { &mut m.id }, + |m: &GridBlock| { &m.id }, + |m: &mut GridBlock| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "start_row_index", - |m: &Block| { &m.start_row_index }, - |m: &mut Block| { &mut m.start_row_index }, + |m: &GridBlock| { &m.start_row_index }, + |m: &mut GridBlock| { &mut m.start_row_index }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "row_count", - |m: &Block| { &m.row_count }, - |m: &mut Block| { &mut m.row_count }, + |m: &GridBlock| { &m.row_count }, + |m: &mut GridBlock| { &mut m.row_count }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Block", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlock", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static Block { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Block::new) + fn default_instance() -> &'static GridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlock::new) } } -impl ::protobuf::Clear for Block { +impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { self.id.clear(); self.start_row_index = 0; @@ -497,20 +497,20 @@ impl ::protobuf::Clear for Block { } } -impl ::std::fmt::Debug for Block { +impl ::std::fmt::Debug for GridBlock { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for Block { +impl ::protobuf::reflect::ProtobufValue for GridBlock { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct BlockMeta { +pub struct GridBlockMeta { // message fields pub block_id: ::std::string::String, pub rows: ::protobuf::RepeatedField, @@ -519,14 +519,14 @@ pub struct BlockMeta { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockMeta { - fn default() -> &'a BlockMeta { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlockMeta { + fn default() -> &'a GridBlockMeta { + ::default_instance() } } -impl BlockMeta { - pub fn new() -> BlockMeta { +impl GridBlockMeta { + pub fn new() -> GridBlockMeta { ::std::default::Default::default() } @@ -582,7 +582,7 @@ impl BlockMeta { } } -impl ::protobuf::Message for BlockMeta { +impl ::protobuf::Message for GridBlockMeta { fn is_initialized(&self) -> bool { for v in &self.rows { if !v.is_initialized() { @@ -665,8 +665,8 @@ impl ::protobuf::Message for BlockMeta { Self::descriptor_static() } - fn new() -> BlockMeta { - BlockMeta::new() + fn new() -> GridBlockMeta { + GridBlockMeta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -675,29 +675,29 @@ impl ::protobuf::Message for BlockMeta { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &BlockMeta| { &m.block_id }, - |m: &mut BlockMeta| { &mut m.block_id }, + |m: &GridBlockMeta| { &m.block_id }, + |m: &mut GridBlockMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "rows", - |m: &BlockMeta| { &m.rows }, - |m: &mut BlockMeta| { &mut m.rows }, + |m: &GridBlockMeta| { &m.rows }, + |m: &mut GridBlockMeta| { &mut m.rows }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockMeta", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMeta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockMeta::new) + fn default_instance() -> &'static GridBlockMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMeta::new) } } -impl ::protobuf::Clear for BlockMeta { +impl ::protobuf::Clear for GridBlockMeta { fn clear(&mut self) { self.block_id.clear(); self.rows.clear(); @@ -705,13 +705,13 @@ impl ::protobuf::Clear for BlockMeta { } } -impl ::std::fmt::Debug for BlockMeta { +impl ::std::fmt::Debug for GridBlockMeta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockMeta { +impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1319,6 +1319,645 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedField { } } +#[derive(PartialEq,Clone,Default)] +pub struct FieldChangeset { + // message fields + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_name: ::std::option::Option, + pub one_of_desc: ::std::option::Option, + pub one_of_field_type: ::std::option::Option, + pub one_of_frozen: ::std::option::Option, + pub one_of_visibility: ::std::option::Option, + pub one_of_width: ::std::option::Option, + pub one_of_type_options: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a FieldChangeset { + fn default() -> &'a FieldChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_name { + name(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_desc { + desc(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_field_type { + field_type(FieldType), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_frozen { + frozen(bool), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_visibility { + visibility(bool), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_width { + width(i32), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_type_options { + type_options(AnyData), +} + +impl FieldChangeset { + pub fn new() -> FieldChangeset { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + match self.one_of_name { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(ref v)) => v, + _ => "", + } + } + pub fn clear_name(&mut self) { + self.one_of_name = ::std::option::Option::None; + } + + pub fn has_name(&self) -> bool { + match self.one_of_name { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(v)) + } + + // Mutable pointer to the field. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(_)) = self.one_of_name { + } else { + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(::std::string::String::new())); + } + match self.one_of_name { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + if self.has_name() { + match self.one_of_name.take() { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // string desc = 3; + + + pub fn get_desc(&self) -> &str { + match self.one_of_desc { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(ref v)) => v, + _ => "", + } + } + pub fn clear_desc(&mut self) { + self.one_of_desc = ::std::option::Option::None; + } + + pub fn has_desc(&self) -> bool { + match self.one_of_desc { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(v)) + } + + // Mutable pointer to the field. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(_)) = self.one_of_desc { + } else { + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(::std::string::String::new())); + } + match self.one_of_desc { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + if self.has_desc() { + match self.one_of_desc.take() { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // .FieldType field_type = 4; + + + pub fn get_field_type(&self) -> FieldType { + match self.one_of_field_type { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) => v, + _ => FieldType::RichText, + } + } + pub fn clear_field_type(&mut self) { + self.one_of_field_type = ::std::option::Option::None; + } + + pub fn has_field_type(&self) -> bool { + match self.one_of_field_type { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: FieldType) { + self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) + } + + // bool frozen = 5; + + + pub fn get_frozen(&self) -> bool { + match self.one_of_frozen { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) => v, + _ => false, + } + } + pub fn clear_frozen(&mut self) { + self.one_of_frozen = ::std::option::Option::None; + } + + pub fn has_frozen(&self) -> bool { + match self.one_of_frozen { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) + } + + // bool visibility = 6; + + + pub fn get_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) => v, + _ => false, + } + } + pub fn clear_visibility(&mut self) { + self.one_of_visibility = ::std::option::Option::None; + } + + pub fn has_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) + } + + // int32 width = 7; + + + pub fn get_width(&self) -> i32 { + match self.one_of_width { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) => v, + _ => 0, + } + } + pub fn clear_width(&mut self) { + self.one_of_width = ::std::option::Option::None; + } + + pub fn has_width(&self) -> bool { + match self.one_of_width { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) + } + + // .AnyData type_options = 8; + + + pub fn get_type_options(&self) -> &AnyData { + match self.one_of_type_options { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v, + _ => ::default_instance(), + } + } + pub fn clear_type_options(&mut self) { + self.one_of_type_options = ::std::option::Option::None; + } + + pub fn has_type_options(&self) -> bool { + match self.one_of_type_options { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_type_options(&mut self, v: AnyData) { + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) + } + + // Mutable pointer to the field. + pub fn mut_type_options(&mut self) -> &mut AnyData { + if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options { + } else { + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(AnyData::new())); + } + match self.one_of_type_options { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_type_options(&mut self) -> AnyData { + if self.has_type_options() { + match self.one_of_type_options.take() { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v, + _ => panic!(), + } + } else { + AnyData::new() + } + } +} + +impl ::protobuf::Message for FieldChangeset { + fn is_initialized(&self) -> bool { + if let Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) = self.one_of_type_options { + if !v.is_initialized() { + return false; + } + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(is.read_string()?)); + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(is.read_string()?)); + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(is.read_enum()?)); + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(is.read_bool()?)); + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(is.read_int32()?)); + }, + 8 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_message()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_name { + match v { + &FieldChangeset_oneof_one_of_name::name(ref v) => { + my_size += ::protobuf::rt::string_size(2, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_desc { + match v { + &FieldChangeset_oneof_one_of_desc::desc(ref v) => { + my_size += ::protobuf::rt::string_size(3, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_type { + match v { + &FieldChangeset_oneof_one_of_field_type::field_type(v) => { + my_size += ::protobuf::rt::enum_size(4, v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_frozen { + match v { + &FieldChangeset_oneof_one_of_frozen::frozen(v) => { + my_size += 2; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &FieldChangeset_oneof_one_of_visibility::visibility(v) => { + my_size += 2; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_width { + match v { + &FieldChangeset_oneof_one_of_width::width(v) => { + my_size += ::protobuf::rt::value_size(7, v, ::protobuf::wire_format::WireTypeVarint); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_type_options { + match v { + &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_name { + match v { + &FieldChangeset_oneof_one_of_name::name(ref v) => { + os.write_string(2, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_desc { + match v { + &FieldChangeset_oneof_one_of_desc::desc(ref v) => { + os.write_string(3, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_type { + match v { + &FieldChangeset_oneof_one_of_field_type::field_type(v) => { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&v))?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_frozen { + match v { + &FieldChangeset_oneof_one_of_frozen::frozen(v) => { + os.write_bool(5, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &FieldChangeset_oneof_one_of_visibility::visibility(v) => { + os.write_bool(6, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_width { + match v { + &FieldChangeset_oneof_one_of_width::width(v) => { + os.write_int32(7, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_type_options { + match v { + &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { + os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> FieldChangeset { + FieldChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &FieldChangeset| { &m.field_id }, + |m: &mut FieldChangeset| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "name", + FieldChangeset::has_name, + FieldChangeset::get_name, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "desc", + FieldChangeset::has_desc, + FieldChangeset::get_desc, + )); + fields.push(::protobuf::reflect::accessor::make_singular_enum_accessor::<_, FieldType>( + "field_type", + FieldChangeset::has_field_type, + FieldChangeset::get_field_type, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "frozen", + FieldChangeset::has_frozen, + FieldChangeset::get_frozen, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "visibility", + FieldChangeset::has_visibility, + FieldChangeset::get_visibility, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "width", + FieldChangeset::has_width, + FieldChangeset::get_width, + )); + fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, AnyData>( + "type_options", + FieldChangeset::has_type_options, + FieldChangeset::get_type_options, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldChangeset::new) + } +} + +impl ::protobuf::Clear for FieldChangeset { + fn clear(&mut self) { + self.field_id.clear(); + self.one_of_name = ::std::option::Option::None; + self.one_of_desc = ::std::option::Option::None; + self.one_of_field_type = ::std::option::Option::None; + self.one_of_frozen = ::std::option::Option::None; + self.one_of_visibility = ::std::option::Option::None; + self.one_of_width = ::std::option::Option::None; + self.one_of_type_options = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct AnyData { // message fields @@ -2537,43 +3176,53 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"c\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"g\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ - s\x12\x1e\n\x06blocks\x18\x03\x20\x03(\x0b2\x06.BlockR\x06blocks\"\\\n\ - \x05Block\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_\ - index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ - \x20\x01(\x05R\x08rowCount\"D\n\tBlockMeta\x12\x19\n\x08block_id\x18\x01\ - \x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.RowM\ - etaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + s\x12\"\n\x06blocks\x18\x03\x20\x03(\x0b2\n.GridBlockR\x06blocks\"`\n\tG\ + ridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_i\ + ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ + \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ + \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ + RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ + R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ - items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\ - \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\ - \x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\ - \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\ - dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\ - ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\ - ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ - \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\ - \n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ - ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ - \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ - dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ - \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ - \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\x01\n\ - \x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06row_\ - id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\ - R\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04dat\ - a\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\x12\ - \x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\ - \x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\ - \x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"\x87\x03\n\x0eFieldChan\ + geset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04\ + name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\t\ + H\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02\ + R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\ + \x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\ + \x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\ + \x08\x20\x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\ + \r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\ + \x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type\ + _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ + eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ + Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ + \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ + \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ + \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ + \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ + \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ + \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ + \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ + \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ + ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ + llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ + \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ + \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ + _of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ + field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ + \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ + R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ + \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ + \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ + o3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index dc00b1e72c..bba2c8c8dc 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,14 +3,14 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated Field fields = 2; - repeated Block blocks = 3; + repeated GridBlock blocks = 3; } -message Block { +message GridBlock { string id = 1; int32 start_row_index = 2; int32 row_count = 3; } -message BlockMeta { +message GridBlockMeta { string block_id = 1; repeated RowMeta rows = 2; } @@ -27,6 +27,16 @@ message Field { message RepeatedField { repeated Field items = 1; } +message FieldChangeset { + string field_id = 1; + oneof one_of_name { string name = 2; }; + oneof one_of_desc { string desc = 3; }; + oneof one_of_field_type { FieldType field_type = 4; }; + oneof one_of_frozen { bool frozen = 5; }; + oneof one_of_visibility { bool visibility = 6; }; + oneof one_of_width { int32 width = 7; }; + oneof one_of_type_options { AnyData type_options = 8; }; +} message AnyData { string type_id = 1; bytes value = 2; From df399d3f3535f8a211e2844c520b43d2726d953a Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 11 Mar 2022 22:07:01 +0800 Subject: [PATCH 031/179] feat: support option enum in pb --- .../flowy-grid-data-model/meta.pb.dart | 82 ++-- .../flowy-grid-data-model/meta.pbjson.dart | 20 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../flowy-derive/src/proto_buf/deserialize.rs | 5 +- .../flowy-derive/src/proto_buf/serialize.rs | 6 + shared-lib/flowy-derive/src/proto_buf/util.rs | 8 +- .../src/protobuf/model/meta.rs | 400 +++++++++--------- .../src/protobuf/proto/meta.proto | 6 +- 8 files changed, 267 insertions(+), 264 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 3b5d6f5dad..344bef10da 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -353,47 +353,6 @@ class Field extends $pb.GeneratedMessage { AnyData ensureTypeOptions() => $_ensure(7); } -class RepeatedField extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) - ..hasRequiredFields = false - ; - - RepeatedField._() : super(); - factory RepeatedField({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedField clone() => RepeatedField()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedField create() => RepeatedField._(); - RepeatedField createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedField? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - enum FieldChangeset_OneOfName { name, notSet @@ -632,6 +591,47 @@ class FieldChangeset extends $pb.GeneratedMessage { AnyData ensureTypeOptions() => $_ensure(7); } +class RepeatedField extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + RepeatedField._() : super(); + factory RepeatedField({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedField clone() => RepeatedField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedField create() => RepeatedField._(); + RepeatedField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedField? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class AnyData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index c955a005fb..04e7384c15 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -75,16 +75,6 @@ const Field$json = const { /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); -@$core.Deprecated('Use repeatedFieldDescriptor instead') -const RepeatedField$json = const { - '1': 'RepeatedField', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', @@ -111,6 +101,16 @@ const FieldChangeset$json = const { /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); +@$core.Deprecated('Use repeatedFieldDescriptor instead') +const RepeatedField$json = const { + '1': 'RepeatedField', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs index a971279b21..e09f7ea847 100644 --- a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs @@ -55,14 +55,11 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option } }?; let bracketed_ty_info = ty_info.bracket_ty_info.as_ref().as_ref(); - let has_func = format_ident!("has_{}", ident.to_string()); - // eprintln!("😁{:#?}", ty_info.primitive_ty); - // eprintln!("{:#?}", ty_info.bracket_ty_info); match ident_category(bracketed_ty_info.unwrap().ident) { TypeCategory::Enum => { let get_func = format_ident!("get_{}", ident.to_string()); - let ty = ty_info.ty; + let ty = bracketed_ty_info.unwrap().ty; Some(quote! { if pb.#has_func() { let enum_de_from_pb = #ty::try_from(&pb.#get_func()).unwrap(); diff --git a/shared-lib/flowy-derive/src/proto_buf/serialize.rs b/shared-lib/flowy-derive/src/proto_buf/serialize.rs index eff797a310..324c26651b 100644 --- a/shared-lib/flowy-derive/src/proto_buf/serialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/serialize.rs @@ -71,6 +71,12 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option None => {} } }), + TypeCategory::Enum => Some(quote! { + match self.#member { + Some(s) => { pb.#set_func(s.try_into().unwrap()) } + None => {} + } + }), _ => Some(quote! { match self.#member { Some(ref s) => { pb.#set_func(s.clone()) } diff --git a/shared-lib/flowy-derive/src/proto_buf/util.rs b/shared-lib/flowy-derive/src/proto_buf/util.rs index 49a5ee1605..ef9391fa0d 100644 --- a/shared-lib/flowy-derive/src/proto_buf/util.rs +++ b/shared-lib/flowy-derive/src/proto_buf/util.rs @@ -74,14 +74,14 @@ pub fn category_from_str(type_str: String) -> TypeCategory { } } - if let Some(protobuf) = CACHE_INFO.get(&TypeCategory::Protobuf) { - if protobuf.contains(&type_str) { + if let Some(protobuf_tys) = CACHE_INFO.get(&TypeCategory::Protobuf) { + if protobuf_tys.contains(&type_str) { return TypeCategory::Protobuf; } } - if let Some(protobuf) = CACHE_INFO.get(&TypeCategory::Enum) { - if protobuf.contains(&type_str) { + if let Some(enum_tys) = CACHE_INFO.get(&TypeCategory::Enum) { + if enum_tys.contains(&type_str) { return TypeCategory::Enum; } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4ef31470a8..4cb13bf25e 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -1153,172 +1153,6 @@ impl ::protobuf::reflect::ProtobufValue for Field { } } -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedField { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedField { - fn default() -> &'a RepeatedField { - ::default_instance() - } -} - -impl RepeatedField { - pub fn new() -> RepeatedField { - ::std::default::Default::default() - } - - // repeated .Field items = 1; - - - pub fn get_items(&self) -> &[Field] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedField { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedField { - RepeatedField::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedField| { &m.items }, - |m: &mut RepeatedField| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedField", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedField { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedField::new) - } -} - -impl ::protobuf::Clear for RepeatedField { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedField { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedField { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldChangeset { // message fields @@ -1958,6 +1792,172 @@ impl ::protobuf::reflect::ProtobufValue for FieldChangeset { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedField { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedField { + fn default() -> &'a RepeatedField { + ::default_instance() + } +} + +impl RepeatedField { + pub fn new() -> RepeatedField { + ::std::default::Default::default() + } + + // repeated .Field items = 1; + + + pub fn get_items(&self) -> &[Field] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedField { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedField { + RepeatedField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedField| { &m.items }, + |m: &mut RepeatedField| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedField::new) + } +} + +impl ::protobuf::Clear for RepeatedField { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct AnyData { // message fields @@ -3189,40 +3189,40 @@ static file_descriptor_proto_data: &'static [u8] = b"\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ - \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ - items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"\x87\x03\n\x0eFieldChan\ - geset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04\ - name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\t\ - H\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02\ - R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\ - \x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\ - \x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\ - \x08\x20\x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\ - \r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\ - \x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type\ - _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ - eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ - Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ - \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ - \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ - \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ - \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ - \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ - \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ - \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ - ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ - llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ - \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ - \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ - _of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ - field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ - \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ - R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ - \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ - \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ - o3\ + \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"\x87\x03\n\x0eFieldChangeset\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\ + \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ + \x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfie\ + ldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\ + \n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\ + \x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\x08\x20\ + \x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0b\ + one_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11\ + one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"\ + -\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ + \x05items\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06ty\ + peId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Ro\ + wMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\ + \x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\ + \x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06h\ + eight\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\ + \x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellM\ + etaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row\ + _id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\ + \x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvis\ + ibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChanges\ + et.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\ + \x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\ + \x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\ + \x11one_of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ + \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\ + \x04\x20\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\ + \x01(\x05R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\ + \x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSele\ + ct\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\ + \x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index bba2c8c8dc..43c7e67d76 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -24,9 +24,6 @@ message Field { int32 width = 7; AnyData type_options = 8; } -message RepeatedField { - repeated Field items = 1; -} message FieldChangeset { string field_id = 1; oneof one_of_name { string name = 2; }; @@ -37,6 +34,9 @@ message FieldChangeset { oneof one_of_width { int32 width = 7; }; oneof one_of_type_options { AnyData type_options = 8; }; } +message RepeatedField { + repeated Field items = 1; +} message AnyData { string type_id = 1; bytes value = 2; From 6579940dc8f3d9f385baf51c471a56672ca1a5e1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 09:30:13 +0800 Subject: [PATCH 032/179] chore: create default grid --- .../flowy-folder-data-model/view.pb.dart | 6 +- .../flowy-folder-data-model/view.pbenum.dart | 4 +- .../flowy-folder-data-model/view.pbjson.dart | 4 +- frontend/rust-lib/flowy-block/src/editor.rs | 7 +- frontend/rust-lib/flowy-block/src/queue.rs | 1 - .../tests/document/document_test.rs | 2 +- .../flowy-block/tests/document/edit_script.rs | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 10 +- .../src/services/folder_editor.rs | 10 +- .../src/services/persistence/migration.rs | 2 +- .../persistence/version_1/view_sql.rs | 4 +- .../src/services/view/controller.rs | 26 ++-- .../tests/workspace/folder_test.rs | 13 +- .../flowy-folder/tests/workspace/helper.rs | 3 +- .../flowy-folder/tests/workspace/script.rs | 23 ++-- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 32 ++++- .../flowy-grid/src/services/grid_builder.rs | 77 ------------ .../flowy-grid/src/services/grid_editor.rs | 68 ++++++----- .../src/services/grid_meta_editor.rs | 34 +++--- .../rust-lib/flowy-grid/src/services/mod.rs | 1 - .../rust-lib/flowy-grid/tests/grid_test.rs | 0 .../flowy-net/src/local_server/persistence.rs | 25 ++-- .../flowy-net/src/local_server/server.rs | 4 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 52 ++++++-- .../src/cache/disk/grid_meta_rev_impl.rs | 4 +- .../src/cache/disk/grid_rev_impl.rs | 4 +- .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 2 - .../src/cache/disk/text_rev_impl.rs | 4 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 1 - frontend/rust-lib/flowy-test/src/helper.rs | 2 +- .../src/client_grid/block_pad.rs | 37 ++++-- .../src/client_grid/grid_builder.rs | 114 ++++++++++++++++++ .../src/client_grid/grid_pad.rs | 21 ++-- .../src/client_grid/mod.rs | 2 + .../src/server_document/document_manager.rs | 31 ++--- .../src/entities/view.rs | 8 +- .../src/protobuf/model/view.rs | 36 +++--- .../src/protobuf/proto/view.proto | 2 +- .../src/user_default.rs | 2 +- .../src/entities/meta.rs | 17 ++- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- 42 files changed, 412 insertions(+), 293 deletions(-) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/grid_builder.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid_test.rs create mode 100644 shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index bc0b49b833..b79716fd25 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -20,7 +20,7 @@ class View extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aInt64(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version') ..aOM(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongings', subBuilder: RepeatedView.create) ..aInt64(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') @@ -274,7 +274,7 @@ class CreateViewPayload extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false @@ -408,7 +408,7 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart index f644361742..aa7b0105b1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart @@ -10,11 +10,11 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; class ViewDataType extends $pb.ProtobufEnum { - static const ViewDataType Block = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Block'); + static const ViewDataType TextBlock = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextBlock'); static const ViewDataType Grid = ViewDataType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Grid'); static const $core.List values = [ - Block, + TextBlock, Grid, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index 87ebb89969..adb1721475 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -12,13 +12,13 @@ import 'dart:typed_data' as $typed_data; const ViewDataType$json = const { '1': 'ViewDataType', '2': const [ - const {'1': 'Block', '2': 0}, + const {'1': 'TextBlock', '2': 0}, const {'1': 'Grid', '2': 1}, ], }; /// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSCQoFQmxvY2sQABIICgRHcmlkEAE='); +final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDQoJVGV4dEJsb2NrEAASCAoER3JpZBAB'); @$core.Deprecated('Use viewDescriptor instead') const View$json = const { '1': 'View', diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs index fa3c1c757c..b5e9e81810 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -1,4 +1,3 @@ -use crate::queue::TextBlockRevisionCompactor; use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; use crate::{ errors::FlowyError, @@ -40,7 +39,7 @@ impl ClientTextBlockEditor { rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { - let document_info = rev_manager.load::(cloud_service).await?; + let document_info = rev_manager.load::(cloud_service).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); @@ -213,8 +212,8 @@ impl ClientTextBlockEditor { } } -struct BlockInfoBuilder(); -impl RevisionObjectBuilder for BlockInfoBuilder { +struct TextBlockInfoBuilder(); +impl RevisionObjectBuilder for TextBlockInfoBuilder { type Output = TextBlockInfo; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index c7683e9f0f..087ed9d189 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -11,7 +11,6 @@ use flowy_collaboration::{ use flowy_error::{FlowyError, FlowyResult}; use flowy_sync::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas}; use futures::stream::StreamExt; -use lib_ot::core::{Attributes, Delta}; use lib_ot::{ core::{Interval, OperationTransformable}, rich_text::{RichTextAttribute, RichTextAttributes, RichTextDelta}, diff --git a/frontend/rust-lib/flowy-block/tests/document/document_test.rs b/frontend/rust-lib/flowy-block/tests/document/document_test.rs index 86fd1d4a2e..df2282d01f 100644 --- a/frontend/rust-lib/flowy-block/tests/document/document_test.rs +++ b/frontend/rust-lib/flowy-block/tests/document/document_test.rs @@ -1,5 +1,5 @@ use crate::document::edit_script::{EditorScript::*, *}; -use flowy_collaboration::entities::revision::RevisionState; +use flowy_sync::disk::RevisionState; use lib_ot::core::{count_utf16_code_units, Interval}; #[tokio::test] diff --git a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs index a06eb24a44..c30ccd8d46 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs @@ -1,6 +1,6 @@ use flowy_block::editor::ClientTextBlockEditor; use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; -use flowy_collaboration::entities::revision::RevisionState; +use flowy_sync::disk::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; use lib_ot::{core::Interval, rich_text::RichTextDelta}; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 3ccb00466e..ffa6fc26cb 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -12,7 +12,7 @@ use bytes::Bytes; use chrono::Utc; use flowy_collaboration::client_document::default::{initial_quill_delta_string, initial_read_me}; -use flowy_collaboration::entities::revision::RepeatedRevision; + use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData}; use flowy_error::FlowyError; use flowy_folder_data_model::entities::view::ViewDataType; @@ -164,7 +164,7 @@ impl FolderManager { let _ = self.persistence.initialize(user_id, &folder_id).await?; let pool = self.persistence.db_pool()?; - let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); let rev_manager = RevisionManager::new(user_id, folder_id.as_ref(), rev_persistence); @@ -214,7 +214,7 @@ impl DefaultFolderBuilder { }; let _ = view_controller.set_latest_view(&view.id); let _ = view_controller - .create_view(&view.id, ViewDataType::Block, Bytes::from(view_data)) + .create_view(&view.id, ViewDataType::TextBlock, Bytes::from(view_data)) .await?; } } @@ -239,7 +239,7 @@ impl FolderManager { pub trait ViewDataProcessor { fn initialize(&self) -> FutureResult<(), FlowyError>; - fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError>; + fn create_container(&self, user_id: &str, view_id: &str, delta_data: Bytes) -> FutureResult<(), FlowyError>; fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError>; @@ -247,7 +247,7 @@ pub trait ViewDataProcessor { fn delta_str(&self, view_id: &str) -> FutureResult; - fn default_view_data(&self, view_id: &str) -> String; + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult; fn data_type(&self) -> ViewDataType; } diff --git a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs index 203c7c4cec..0a5dd7f794 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -8,14 +8,14 @@ use crate::manager::FolderId; use bytes::Bytes; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_sync::disk::RevisionDiskCache; + use flowy_sync::{ - RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, - RevisionWebSocket, RevisionWebSocketManager, + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, + RevisionWebSocketManager, }; use lib_infra::future::FutureResult; -use lib_ot::core::{Delta, PlainTextAttributes}; -use lib_sqlite::ConnectionPool; +use lib_ot::core::PlainTextAttributes; + use parking_lot::RwLock; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs index 20e6d71c66..c08a4c226e 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -88,7 +88,7 @@ impl FolderMigration { return Ok(None); } let pool = self.database.db_pool()?; - let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); let (revisions, _) = RevisionLoader { object_id: folder_id.as_ref().to_owned(), diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs index c854021b80..a41f3c49c2 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs @@ -84,7 +84,7 @@ pub(crate) struct ViewTable { impl ViewTable { pub fn new(view: View) -> Self { let data_type = match view.data_type { - ViewDataType::Block => SqlViewDataType::Block, + ViewDataType::TextBlock => SqlViewDataType::Block, ViewDataType::Grid => SqlViewDataType::Grid, }; @@ -106,7 +106,7 @@ impl ViewTable { impl std::convert::From for View { fn from(table: ViewTable) -> Self { let data_type = match table.view_type { - SqlViewDataType::Block => ViewDataType::Block, + SqlViewDataType::Block => ViewDataType::TextBlock, SqlViewDataType::Grid => ViewDataType::Grid, }; diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index 4722aaad5d..79ce91e3bb 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -13,10 +13,7 @@ use crate::{ }, }; use bytes::Bytes; -use flowy_collaboration::entities::{ - revision::{RepeatedRevision, Revision}, - text_block_info::TextBlockId, -}; +use flowy_collaboration::entities::text_block_info::TextBlockId; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::ViewDataType; use futures::{FutureExt, StreamExt}; @@ -58,18 +55,18 @@ impl ViewController { #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] pub(crate) async fn create_view_from_params(&self, mut params: CreateViewParams) -> Result { let processor = self.get_data_processor(¶ms.data_type)?; - let content = if params.data.is_empty() { - let default_view_data = processor.default_view_data(¶ms.view_id); - params.data = default_view_data.clone(); - default_view_data + + if params.data.is_empty() { + let user_id = self.user.user_id()?; + let view_data = processor.create_default_view(&user_id, ¶ms.view_id).await?; + params.data = view_data; } else { - params.data.clone() + let delta_data = Bytes::from(params.data.clone()); + let _ = self + .create_view(¶ms.view_id, params.data_type.clone(), delta_data) + .await?; }; - let delta_data = Bytes::from(content); - let _ = self - .create_view(¶ms.view_id, params.data_type.clone(), delta_data) - .await?; let view = self.create_view_on_server(params).await?; let _ = self.create_view_on_local(view.clone()).await?; Ok(view) @@ -86,9 +83,8 @@ impl ViewController { return Err(FlowyError::internal().context("The content of the view should not be empty")); } let user_id = self.user.user_id()?; - let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, view_id, delta_data).into(); let processor = self.get_data_processor(&data_type)?; - let _ = processor.create_container(view_id, repeated_revision).await?; + let _ = processor.create_container(&user_id, view_id, delta_data).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs index 18a11d9a0b..7dd5b66e2f 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,6 +1,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; -use flowy_collaboration::{client_document::default::initial_quill_delta_string, entities::revision::RevisionState}; + use flowy_folder::entities::workspace::CreateWorkspacePayload; +use flowy_sync::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; #[tokio::test] @@ -168,16 +169,6 @@ async fn view_update() { assert_eq!(test.view.name, new_name); } -#[tokio::test] -async fn open_document_view() { - let mut test = FolderTest::new().await; - assert_eq!(test.document_info, None); - - test.run_scripts(vec![OpenDocument]).await; - let document_info = test.document_info.unwrap(); - assert_eq!(document_info.text, initial_quill_delta_string()); -} - #[tokio::test] #[should_panic] async fn view_delete() { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs index 393c0f5699..93e2ff2b7f 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs @@ -161,7 +161,8 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { .await; } -pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { +#[allow(dead_code)] +pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { let view_id: ViewId = view_id.into(); FolderEventBuilder::new(sdk.clone()) .event(SetLatestView) diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index e4298b54e7..7674ca0a54 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -1,5 +1,5 @@ use crate::helper::*; -use flowy_collaboration::entities::{revision::RevisionState, text_block_info::TextBlockInfo}; + use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; use flowy_folder_data_model::entities::{ app::{App, RepeatedApp}, @@ -7,6 +7,7 @@ use flowy_folder_data_model::entities::{ view::{RepeatedView, View, ViewDataType}, workspace::Workspace, }; +use flowy_sync::disk::RevisionState; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::FlowySDKTest; use std::{sync::Arc, time::Duration}; @@ -42,9 +43,6 @@ pub enum FolderScript { ReadTrash, DeleteAllTrash, - // Document - OpenDocument, - // Sync AssertCurrentRevId(i64), AssertNextSyncRevId(Option), @@ -58,7 +56,6 @@ pub struct FolderTest { pub app: App, pub view: View, pub trash: Vec, - pub document_info: Option, // pub folder_editor: } @@ -68,7 +65,14 @@ impl FolderTest { let _ = sdk.init_user().await; let mut workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").await; let mut app = create_app(&sdk, &workspace.id, "Folder App", "Folder test app").await; - let view = create_view(&sdk, &app.id, "Folder View", "Folder test view", ViewDataType::Block).await; + let view = create_view( + &sdk, + &app.id, + "Folder View", + "Folder test view", + ViewDataType::TextBlock, + ) + .await; app.belongings = RepeatedView { items: vec![view.clone()], }; @@ -83,7 +87,6 @@ impl FolderTest { app, view, trash: vec![], - document_info: None, } } @@ -146,7 +149,7 @@ impl FolderTest { } FolderScript::CreateView { name, desc } => { - let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::Block).await; + let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::TextBlock).await; self.view = view; } FolderScript::AssertView(view) => { @@ -179,10 +182,6 @@ impl FolderTest { delete_all_trash(sdk).await; self.trash = vec![]; } - FolderScript::OpenDocument => { - let document_info = open_document(sdk, &self.view.id).await; - self.document_info = Some(document_info); - } FolderScript::AssertRevisionState { rev_id, state } => { let record = cache.get(rev_id).await.unwrap(); assert_eq!(record.state, state); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 8c91bf1341..b621d30a69 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -46,7 +46,7 @@ pub(crate) async fn create_row_handler( ) -> Result<(), FlowyError> { let id: GridId = data.into_inner(); let editor = manager.get_grid_editor(id.as_ref())?; - let _ = editor.create_empty_row().await?; + let _ = editor.create_row().await?; Ok(()) } @@ -55,7 +55,7 @@ pub(crate) async fn update_cell_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let cell: Cell = data.into_inner(); + let _cell: Cell = data.into_inner(); // let editor = manager.get_grid_editor(id.as_ref())?; // let _ = editor.create_empty_row().await?; Ok(()) diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 6c5aa8236a..05e61b26ce 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,13 +1,10 @@ use crate::services::grid_editor::ClientGridEditor; -use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; +use crate::services::kv_persistence::GridKVPersistence; use dashmap::DashMap; - use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, RowMeta}; +use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; - -use flowy_sync::disk::SQLiteGridRevisionPersistence; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -47,6 +44,19 @@ impl GridManager { Ok(()) } + #[tracing::instrument(level = "debug", skip_all, err)] + pub async fn create_grid_block_meta>( + &self, + block_id: T, + revisions: RepeatedRevision, + ) -> FlowyResult<()> { + let block_id = block_id.as_ref(); + let db_pool = self.grid_user.db_pool()?; + let rev_manager = self.make_grid_block_meta_rev_manager(block_id, db_pool)?; + let _ = rev_manager.reset_object(revisions).await?; + Ok(()) + } + #[tracing::instrument(level = "debug", skip_all, fields(grid_id), err)] pub async fn open_grid>(&self, grid_id: T) -> FlowyResult> { let grid_id = grid_id.as_ref(); @@ -112,6 +122,18 @@ impl GridManager { Ok(rev_manager) } + fn make_grid_block_meta_rev_manager( + &self, + block_d: &str, + pool: Arc, + ) -> FlowyResult { + let user_id = self.grid_user.user_id()?; + let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_d, disk_cache)); + let rev_manager = RevisionManager::new(&user_id, block_d, rev_persistence); + Ok(rev_manager) + } + fn get_kv_persistence(&self) -> FlowyResult> { let read_guard = self.kv_persistence.read(); if read_guard.is_some() { diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs deleted file mode 100644 index e74ad692d3..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::manager::GridManager; -use flowy_collaboration::client_grid::make_grid_delta; -use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{CellMeta, Field, FieldType, Grid, GridMeta, RowMeta, RowOrder}; -use lib_infra::uuid; -use std::sync::Arc; - -pub struct GridBuilder { - grid_manager: Arc, - grid_id: String, - fields: Vec, - rows: Vec, -} - -impl GridBuilder { - pub fn new(grid_id: &str, grid_manager: Arc) -> Self { - Self { - grid_manager, - grid_id: grid_id.to_owned(), - fields: vec![], - rows: vec![], - } - } - - pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { - let field = Field::new(&uuid(), name, desc, field_type); - self.fields.push(field); - self - } - - pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); - self.rows.push(row); - self - } - - pub fn add_row(mut self, cells: Vec) -> Self { - let row = RowMeta::new(&uuid(), &self.grid_id, cells); - self.rows.push(row); - self - } - - pub fn build(self) -> FlowyResult { - let grid_meta = GridMeta { - grid_id: self.grid_id, - fields: self.fields, - blocks: vec![], - }; - - // let _ = check_rows(&self.fields, &self.rows)?; - let delta = make_grid_delta(&grid_meta); - Ok(delta.to_delta_str()) - } -} - -#[allow(dead_code)] -fn check_rows(fields: &[Field], rows: &[RowMeta]) -> FlowyResult<()> { - let field_ids = fields.iter().map(|field| &field.id).collect::>(); - for row in rows { - let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); - if cell_field_ids != field_ids { - let msg = format!("{:?} contains invalid cells", row); - return Err(FlowyError::internal().context(msg)); - } - } - Ok(()) -} - -pub fn make_default_grid(grid_id: &str, grid_manager: Arc) -> String { - GridBuilder::new(grid_id, grid_manager) - .add_field("Name", "", FieldType::RichText) - .add_field("Tags", "", FieldType::SingleSelect) - .add_empty_row() - .add_empty_row() - .build() - .unwrap() -} diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 4fb93c16b2..f9cf627d83 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,6 +1,5 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::stringify::stringify_deserialize; use crate::services::grid_meta_editor::ClientGridBlockMetaEditor; use bytes::Bytes; @@ -10,14 +9,14 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, + Field, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, +}; +use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; +use flowy_sync::{ + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, }; -use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; -use lib_infra::uuid; -use lib_ot::core::{Delta, PlainTextAttributes}; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; -use std::collections::HashMap; +use lib_ot::core::PlainTextAttributes; use std::sync::Arc; use tokio::sync::RwLock; @@ -40,10 +39,11 @@ impl ClientGridEditor { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(cloud).await?; - let rev_manager = Arc::new(rev_manager); let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new()); + + let block_meta_manager = + Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks()).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -65,25 +65,15 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_empty_row(&self) -> FlowyResult<()> { - // let _ = self.modify(|grid| { - // - // - // grid.blocks - // - // }).await?; + pub async fn create_row(&self) -> FlowyResult<()> { todo!() } - async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { todo!() } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { - todo!() - } - - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { + pub async fn delete_rows(&self, _ids: Vec) -> FlowyResult<()> { todo!() } @@ -188,13 +178,17 @@ struct GridBlockMetaEditorManager { } impl GridBlockMetaEditorManager { - fn new() -> Self { - Self { - editor_map: DashMap::new(), - } + async fn new(user: &Arc, blocks: Vec) -> FlowyResult { + let editor_map = make_block_meta_editor_map(user, blocks).await?; + let manager = Self { editor_map }; + Ok(manager) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + async fn get_editor(&self, _block_id: &str) -> Arc { + todo!() + } + + pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { // let ids = row_orders // .items // .into_iter() @@ -245,3 +239,23 @@ impl GridBlockMetaEditorManager { todo!() } } + +async fn make_block_meta_editor_map( + user: &Arc, + blocks: Vec, +) -> FlowyResult>> { + let token = user.token()?; + let user_id = user.user_id()?; + let pool = user.db_pool()?; + + let editor_map = DashMap::new(); + for block in blocks { + let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool.clone())); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, &block.id, disk_cache)); + let rev_manager = RevisionManager::new(&user_id, &block.id, rev_persistence); + let editor = ClientGridBlockMetaEditor::new(&user_id, &token, &block.id, rev_manager).await?; + editor_map.insert(block.id, Arc::new(editor)); + } + + Ok(editor_map) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 3e3e5e82d3..6704d6a718 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -3,17 +3,16 @@ use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::RowMeta; +use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; -use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; use std::sync::Arc; use tokio::sync::RwLock; pub struct ClientGridBlockMetaEditor { user_id: String, - block_id: String, + pub block_id: String, meta_pad: Arc>, rev_manager: Arc, } @@ -22,7 +21,7 @@ impl ClientGridBlockMetaEditor { pub async fn new( user_id: &str, token: &str, - block_id: String, + block_id: &str, mut rev_manager: RevisionManager, ) -> FlowyResult { let cloud = Arc::new(GridBlockMetaRevisionCloudService { @@ -32,6 +31,7 @@ impl ClientGridBlockMetaEditor { let meta_pad = Arc::new(RwLock::new(block_meta_pad)); let rev_manager = Arc::new(rev_manager); let user_id = user_id.to_owned(); + let block_id = block_id.to_owned(); Ok(Self { user_id, block_id, @@ -40,25 +40,27 @@ impl ClientGridBlockMetaEditor { }) } - pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RowMeta::new(&uuid(), &self.block_id, vec![]); - self.create_row(row).await?; - Ok(()) - } - - async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { - // let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; - // self.cell_map.insert(row.id.clone(), row.clone()); - // let _ = self.kv_persistence.set(row)?; + async fn create_row(&self) -> FlowyResult<()> { + let row = RowMeta::new(&self.block_id, vec![]); + let _ = self.modify(|pad| Ok(pad.add_row(row)?)).await?; Ok(()) } pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { - // let _ = self.modify(|grid| Ok(grid.delete_rows(&ids)?)).await?; - // let _ = self.kv.batch_delete(ids)?; + let _ = self.modify(|pad| Ok(pad.delete_rows(&ids)?)).await?; Ok(()) } + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + let _ = self.modify(|pad| Ok(pad.update_row(changeset)?)).await?; + Ok(()) + } + + pub async fn get_rows(&self, row_ids: Vec) -> FlowyResult> { + let rows = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(rows) + } + async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 226426aeb7..340a260b09 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,7 +1,6 @@ mod util; pub mod cell_data; -pub mod grid_builder; pub mod grid_editor; pub mod grid_meta_editor; pub mod kv_persistence; diff --git a/frontend/rust-lib/flowy-grid/tests/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid_test.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs index 89e107e44f..525b487ce4 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs @@ -29,25 +29,25 @@ pub trait RevisionCloudStorage: Send + Sync { ) -> BoxResultFuture<(), CollaborateError>; } -pub(crate) struct LocalDocumentCloudPersistence { +pub(crate) struct LocalTextBlockCloudPersistence { storage: Arc, } -impl Debug for LocalDocumentCloudPersistence { +impl Debug for LocalTextBlockCloudPersistence { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str("LocalRevisionCloudPersistence") } } -impl std::default::Default for LocalDocumentCloudPersistence { +impl std::default::Default for LocalTextBlockCloudPersistence { fn default() -> Self { - LocalDocumentCloudPersistence { + LocalTextBlockCloudPersistence { storage: Arc::new(MemoryDocumentCloudStorage::default()), } } } -impl FolderCloudPersistence for LocalDocumentCloudPersistence { +impl FolderCloudPersistence for LocalTextBlockCloudPersistence { fn read_folder(&self, _user_id: &str, folder_id: &str) -> BoxResultFuture { let storage = self.storage.clone(); let folder_id = folder_id.to_owned(); @@ -110,8 +110,8 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence { } } -impl DocumentCloudPersistence for LocalDocumentCloudPersistence { - fn read_document(&self, doc_id: &str) -> BoxResultFuture { +impl TextBlockCloudPersistence for LocalTextBlockCloudPersistence { + fn read_text_block(&self, doc_id: &str) -> BoxResultFuture { let storage = self.storage.clone(); let doc_id = doc_id.to_owned(); Box::pin(async move { @@ -123,7 +123,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn create_document( + fn create_text_block( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, @@ -136,7 +136,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn read_document_revisions( + fn read_text_block_revisions( &self, doc_id: &str, rev_ids: Option>, @@ -150,7 +150,10 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn save_document_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { + fn save_text_block_revisions( + &self, + repeated_revision: RepeatedRevisionPB, + ) -> BoxResultFuture<(), CollaborateError> { let storage = self.storage.clone(); Box::pin(async move { let _ = storage.set_revisions(repeated_revision).await?; @@ -158,7 +161,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn reset_document(&self, doc_id: &str, revisions: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { + fn reset_text_block(&self, doc_id: &str, revisions: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { let storage = self.storage.clone(); let doc_id = doc_id.to_owned(); Box::pin(async move { diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index b25bf9429f..646ca04e0f 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -1,4 +1,4 @@ -use crate::local_server::persistence::LocalDocumentCloudPersistence; +use crate::local_server::persistence::LocalTextBlockCloudPersistence; use async_stream::stream; use bytes::Bytes; use flowy_collaboration::{ @@ -38,7 +38,7 @@ impl LocalServer { client_ws_sender: mpsc::UnboundedSender, client_ws_receiver: broadcast::Sender, ) -> Self { - let persistence = Arc::new(LocalDocumentCloudPersistence::default()); + let persistence = Arc::new(LocalTextBlockCloudPersistence::default()); let doc_manager = Arc::new(ServerDocumentManager::new(persistence.clone())); let folder_manager = Arc::new(ServerFolderManager::new(persistence)); let stop_tx = RwLock::new(None); diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 6fea7bbe73..e0906cc7f1 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,7 +1,8 @@ use bytes::Bytes; use flowy_block::TextBlockManager; use flowy_collaboration::client_document::default::initial_quill_delta_string; -use flowy_collaboration::entities::revision::RepeatedRevision; +use flowy_collaboration::client_grid::make_default_grid; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; @@ -12,7 +13,6 @@ use flowy_folder::{ manager::FolderManager, }; use flowy_grid::manager::GridManager; -use flowy_grid::services::grid_builder::make_default_grid; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -140,9 +140,10 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { FutureResult::new(async move { manager.init() }) } - fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); + fn create_container(&self, user_id: &str, view_id: &str, delta_data: Bytes) -> FutureResult<(), FlowyError> { + let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, view_id, delta_data).into(); let view_id = view_id.to_string(); + let manager = self.0.clone(); FutureResult::new(async move { let _ = manager.create_block(view_id, repeated_revision).await?; Ok(()) @@ -177,12 +178,21 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { }) } - fn default_view_data(&self, _view_id: &str) -> String { - initial_quill_delta_string() + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + let user_id = user_id.to_string(); + let view_id = view_id.to_string(); + let manager = self.0.clone(); + FutureResult::new(async move { + let view_data = initial_quill_delta_string(); + let delta_data = Bytes::from(view_data.clone()); + let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, &view_id, delta_data).into(); + let _ = manager.create_block(view_id, repeated_revision).await?; + Ok(view_data) + }) } fn data_type(&self) -> ViewDataType { - ViewDataType::Block + ViewDataType::TextBlock } } @@ -192,9 +202,10 @@ impl ViewDataProcessor for GridViewDataProcessor { FutureResult::new(async { Ok(()) }) } - fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { - let grid_manager = self.0.clone(); + fn create_container(&self, user_id: &str, view_id: &str, delta_data: Bytes) -> FutureResult<(), FlowyError> { + let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, view_id, delta_data).into(); let view_id = view_id.to_string(); + let grid_manager = self.0.clone(); FutureResult::new(async move { let _ = grid_manager.create_grid(view_id, repeated_revision).await?; Ok(()) @@ -229,8 +240,27 @@ impl ViewDataProcessor for GridViewDataProcessor { }) } - fn default_view_data(&self, view_id: &str) -> String { - make_default_grid(view_id, self.0.clone()) + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + let info = make_default_grid(view_id); + let user_id = user_id.to_string(); + let view_id = view_id.to_string(); + let grid_manager = self.0.clone(); + + FutureResult::new(async move { + let grid_delta_data = Bytes::from(info.grid_delta.to_delta_str()); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &view_id, grid_delta_data).into(); + let _ = grid_manager.create_grid(&view_id, repeated_revision).await?; + + let block_meta_delta_data = Bytes::from(info.grid_block_meta_delta.to_delta_str()); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &info.block_id, block_meta_delta_data).into(); + let _ = grid_manager + .create_grid_block_meta(&info.block_id, repeated_revision) + .await?; + + Ok(info.grid_delta.to_delta_str()) + }) } fn data_type(&self) -> ViewDataType { diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs index ba4a0950af..4cd46058bf 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs @@ -1,10 +1,10 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; -use crate::memory::RevisionMemoryCacheDelegate; + use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange}, + entities::revision::{Revision, RevisionRange}, util::md5, }; use flowy_database::{ diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs index 385bc812c7..414bbb96c9 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs @@ -1,10 +1,10 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; -use crate::memory::RevisionMemoryCacheDelegate; + use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange}, + entities::revision::{Revision, RevisionRange}, util::md5, }; use flowy_database::{ diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index e261f8d7ec..3a278afe36 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -8,8 +8,6 @@ pub use grid_meta_rev_impl::*; pub use grid_rev_impl::*; pub use text_rev_impl::*; -use crate::memory::RevisionMemoryCacheDelegate; -use diesel::SqliteConnection; use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; use std::fmt::Debug; diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs index 0d780f824a..13a8298916 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs @@ -1,10 +1,10 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; -use crate::memory::RevisionMemoryCacheDelegate; + use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange}, + entities::revision::{RevType, Revision, RevisionRange}, util::md5, }; use flowy_database::{ diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index ae26bbf68c..d0ed5240c8 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -7,7 +7,6 @@ use flowy_collaboration::{ }; use flowy_error::{FlowyError, FlowyResult}; use lib_infra::future::FutureResult; -use lib_ot::core::{Attributes, Delta}; use std::sync::Arc; pub trait RevisionCloudService: Send + Sync { diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index f28f7d35b0..83277b22c6 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -88,7 +88,7 @@ async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View { name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), - data_type: ViewDataType::Block, + data_type: ViewDataType::TextBlock, ext_data: "".to_string(), plugin_type: 0, }; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 0ca0d5ee03..1252f0d842 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,10 +1,11 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset, RowOrder}; +use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use std::sync::Arc; pub type GridBlockMetaDelta = PlainTextDelta; @@ -49,6 +50,25 @@ impl GridBlockMetaPad { }) } + pub fn get_rows(&self, row_ids: Vec) -> CollaborateResult> { + let row_map = self + .rows + .iter() + .map(|row| (&row.id, row.clone())) + .collect::>>(); + + Ok(row_ids + .iter() + .flat_map(|row_id| match row_map.get(row_id) { + None => { + tracing::error!("Can't find the row with id: {}", row_id); + None + } + Some(row) => Some((**row).clone()), + }) + .collect::>()) + } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { @@ -123,12 +143,6 @@ impl GridBlockMetaPad { } } -fn json_from_grid(block_meta: &Arc) -> CollaborateResult { - let json = serde_json::to_string(block_meta) - .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; - Ok(json) -} - pub struct GridBlockMetaChange { pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. @@ -165,9 +179,8 @@ impl std::default::Default for GridBlockMetaPad { #[cfg(test)] mod tests { - use crate::client_grid::{GridBlockMetaDelta, GridMetaPad}; + use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; - use std::str::FromStr; #[test] fn block_meta_add_row() { @@ -227,7 +240,7 @@ mod tests { cell_by_field_id: Default::default(), }; - let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let _ = pad.add_row(row).unwrap().unwrap(); let change = pad.update_row(changeset).unwrap().unwrap(); assert_eq!( @@ -241,8 +254,8 @@ mod tests { ); } - fn test_pad() -> GridMetaPad { + fn test_pad() -> GridBlockMetaPad { let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - GridMetaPad::from_delta(delta).unwrap() + GridBlockMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs new file mode 100644 index 0000000000..dbc41e28ae --- /dev/null +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -0,0 +1,114 @@ +use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; +use crate::errors::{CollaborateError, CollaborateResult}; +use flowy_grid_data_model::entities::{Field, FieldType, GridBlock, GridBlockMeta, GridMeta, RowMeta}; + +pub struct GridBuilder { + grid_id: String, + fields: Vec, + grid_block: GridBlock, + grid_block_meta: GridBlockMeta, +} + +impl GridBuilder { + pub fn new(grid_id: &str) -> Self { + let grid_block = GridBlock::new(); + let grid_block_meta = GridBlockMeta { + block_id: grid_block.id.clone(), + rows: vec![], + }; + + Self { + grid_id: grid_id.to_owned(), + fields: vec![], + grid_block, + grid_block_meta, + } + } + + pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { + let field = Field::new(name, desc, field_type); + self.fields.push(field); + self + } + + pub fn add_empty_row(mut self) -> Self { + let row = RowMeta::new(&self.grid_block.id, vec![]); + self.grid_block_meta.rows.push(row); + self + } + + pub fn build(self) -> CollaborateResult { + let block_id = self.grid_block.id.clone(); + let grid_meta = GridMeta { + grid_id: self.grid_id, + fields: self.fields, + blocks: vec![self.grid_block], + }; + // let _ = check_rows(&self.fields, &self.rows)?; + let grid_delta = make_grid_delta(&grid_meta); + let grid_block_meta_delta = make_block_meta_delta(&self.grid_block_meta); + Ok(BuildGridInfo { + grid_delta, + block_id, + grid_block_meta_delta, + }) + } +} + +pub struct BuildGridInfo { + pub grid_delta: GridMetaDelta, + pub block_id: String, + pub grid_block_meta_delta: GridBlockMetaDelta, +} + +#[allow(dead_code)] +fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { + let field_ids = fields.iter().map(|field| &field.id).collect::>(); + for row in rows { + let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); + if cell_field_ids != field_ids { + let msg = format!("{:?} contains invalid cells", row); + return Err(CollaborateError::internal().context(msg)); + } + } + Ok(()) +} + +pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { + GridBuilder::new(grid_id) + .add_field("Name", "", FieldType::RichText) + .add_field("Tags", "", FieldType::SingleSelect) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() + .unwrap() +} + +#[cfg(test)] +mod tests { + use crate::client_grid::GridBuilder; + use flowy_grid_data_model::entities::{FieldType, GridBlockMeta, GridMeta}; + + #[test] + fn create_default_grid_test() { + let info = GridBuilder::new("1") + .add_field("Name", "", FieldType::RichText) + .add_field("Tags", "", FieldType::SingleSelect) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() + .unwrap(); + + let grid_meta: GridMeta = serde_json::from_str(&info.grid_delta.to_str().unwrap()).unwrap(); + assert_eq!(grid_meta.fields.len(), 2); + assert_eq!(grid_meta.blocks.len(), 1); + + let grid_block_meta: GridBlockMeta = + serde_json::from_str(&info.grid_block_meta_delta.to_str().unwrap()).unwrap(); + assert_eq!(grid_block_meta.rows.len(), 3); + + assert_eq!(grid_meta.blocks[0].id, grid_block_meta.block_id); + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 6e04107e44..5b99afd9c2 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,24 +2,23 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, FieldOrder, Grid, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, - RepeatedFieldOrder, RowMeta, RowOrder, + Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; use std::sync::Arc; -pub type GridDelta = PlainTextDelta; +pub type GridMetaDelta = PlainTextDelta; pub type GridDeltaBuilder = PlainTextDeltaBuilder; pub struct GridMetaPad { pub(crate) grid_meta: Arc, - pub(crate) delta: GridDelta, + pub(crate) delta: GridMetaDelta, } impl GridMetaPad { - pub fn from_delta(delta: GridDelta) -> CollaborateResult { + pub fn from_delta(delta: GridMetaDelta) -> CollaborateResult { let s = delta.to_str()?; let grid: GridMeta = serde_json::from_str(&s) .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?; @@ -31,7 +30,7 @@ impl GridMetaPad { } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { - let grid_delta: GridDelta = make_delta_from_revisions::(revisions)?; + let grid_delta: GridMetaDelta = make_delta_from_revisions::(revisions)?; Self::from_delta(grid_delta) } @@ -64,7 +63,7 @@ impl GridMetaPad { .iter() .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { None => { - tracing::error!("Can't find the field with {}", field_order.field_id); + tracing::error!("Can't find the field with id: {}", field_order.field_id); None } Some(field) => Some((*field).clone()), @@ -123,6 +122,10 @@ impl GridMetaPad { }) } + pub fn get_blocks(&self) -> Vec { + self.grid_meta.blocks.clone() + } + pub fn update_block(&mut self, change: GridBlockChangeset) -> CollaborateResult> { let block_id = change.block_id.clone(); self.modify_block(&block_id, |block| { @@ -204,12 +207,12 @@ fn json_from_grid(grid: &Arc) -> CollaborateResult { } pub struct GridChange { - pub delta: GridDelta, + pub delta: GridMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_grid_delta(grid_meta: &GridMeta) -> GridDelta { +pub fn make_grid_delta(grid_meta: &GridMeta) -> GridMetaDelta { let json = serde_json::to_string(&grid_meta).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index 8ecb671968..5fbaa170b4 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,5 +1,7 @@ mod block_pad; +mod grid_builder; mod grid_pad; pub use block_pad::*; +pub use grid_builder::*; pub use grid_pad::*; diff --git a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs index 8a5b5f7304..3232f0e9ca 100644 --- a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs +++ b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs @@ -17,41 +17,42 @@ use tokio::{ task::spawn_blocking, }; -pub trait DocumentCloudPersistence: Send + Sync + Debug { - fn read_document(&self, doc_id: &str) -> BoxResultFuture; +pub trait TextBlockCloudPersistence: Send + Sync + Debug { + fn read_text_block(&self, doc_id: &str) -> BoxResultFuture; - fn create_document( + fn create_text_block( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, ) -> BoxResultFuture, CollaborateError>; - fn read_document_revisions( + fn read_text_block_revisions( &self, doc_id: &str, rev_ids: Option>, ) -> BoxResultFuture, CollaborateError>; - fn save_document_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError>; + fn save_text_block_revisions(&self, repeated_revision: RepeatedRevisionPB) + -> BoxResultFuture<(), CollaborateError>; - fn reset_document( + fn reset_text_block( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, ) -> BoxResultFuture<(), CollaborateError>; } -impl RevisionSyncPersistence for Arc { +impl RevisionSyncPersistence for Arc { fn read_revisions( &self, object_id: &str, rev_ids: Option>, ) -> BoxResultFuture, CollaborateError> { - (**self).read_document_revisions(object_id, rev_ids) + (**self).read_text_block_revisions(object_id, rev_ids) } fn save_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { - (**self).save_document_revisions(repeated_revision) + (**self).save_text_block_revisions(repeated_revision) } fn reset_object( @@ -59,17 +60,17 @@ impl RevisionSyncPersistence for Arc { object_id: &str, repeated_revision: RepeatedRevisionPB, ) -> BoxResultFuture<(), CollaborateError> { - (**self).reset_document(object_id, repeated_revision) + (**self).reset_text_block(object_id, repeated_revision) } } pub struct ServerDocumentManager { document_handlers: Arc>>>, - persistence: Arc, + persistence: Arc, } impl ServerDocumentManager { - pub fn new(persistence: Arc) -> Self { + pub fn new(persistence: Arc) -> Self { Self { document_handlers: Arc::new(RwLock::new(HashMap::new())), persistence, @@ -151,7 +152,7 @@ impl ServerDocumentManager { } let mut write_guard = self.document_handlers.write().await; - match self.persistence.read_document(doc_id).await { + match self.persistence.read_text_block(doc_id).await { Ok(doc) => { let handler = self.create_document_handler(doc).await.map_err(internal_error).unwrap(); write_guard.insert(doc_id.to_owned(), handler.clone()); @@ -168,7 +169,7 @@ impl ServerDocumentManager { doc_id: &str, repeated_revision: RepeatedRevisionPB, ) -> Result, CollaborateError> { - match self.persistence.create_document(doc_id, repeated_revision).await? { + match self.persistence.create_text_block(doc_id, repeated_revision).await? { None => Err(CollaborateError::internal().context("Create document info from revisions failed")), Some(doc) => { let handler = self.create_document_handler(doc).await?; @@ -205,7 +206,7 @@ struct OpenDocumentHandler { } impl OpenDocumentHandler { - fn new(doc: TextBlockInfo, persistence: Arc) -> Result { + fn new(doc: TextBlockInfo, persistence: Arc) -> Result { let doc_id = doc.block_id.clone(); let (sender, receiver) = mpsc::channel(1000); let users = DashMap::new(); diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index 307850d396..8d6ac05406 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -83,24 +83,24 @@ impl std::convert::From for Trash { #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)] #[repr(u8)] pub enum ViewDataType { - Block = 0, + TextBlock = 0, Grid = 1, } impl std::default::Default for ViewDataType { fn default() -> Self { - ViewDataType::Block + ViewDataType::TextBlock } } impl std::convert::From for ViewDataType { fn from(val: i32) -> Self { match val { - 0 => ViewDataType::Block, + 0 => ViewDataType::TextBlock, 1 => ViewDataType::Grid, _ => { log::error!("Invalid view type: {}", val); - ViewDataType::Block + ViewDataType::TextBlock } } } diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index 26173acfaf..bb38b794f2 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -165,7 +165,7 @@ impl View { self.data_type } pub fn clear_data_type(&mut self) { - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; } // Param is passed by value, moved @@ -409,7 +409,7 @@ impl ::protobuf::Message for View { if !self.desc.is_empty() { my_size += ::protobuf::rt::string_size(4, &self.desc); } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } if self.version != 0 { @@ -452,7 +452,7 @@ impl ::protobuf::Message for View { if !self.desc.is_empty() { os.write_string(4, &self.desc)?; } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } if self.version != 0 { @@ -596,7 +596,7 @@ impl ::protobuf::Clear for View { self.belong_to_id.clear(); self.name.clear(); self.desc.clear(); - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; self.version = 0; self.belongings.clear(); self.modified_time = 0; @@ -952,7 +952,7 @@ impl CreateViewPayload { self.data_type } pub fn clear_data_type(&mut self) { - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; } // Param is passed by value, moved @@ -1060,7 +1060,7 @@ impl ::protobuf::Message for CreateViewPayload { if !self.desc.is_empty() { my_size += ::protobuf::rt::string_size(3, &self.desc); } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } if !self.ext_data.is_empty() { @@ -1091,7 +1091,7 @@ impl ::protobuf::Message for CreateViewPayload { if !self.desc.is_empty() { os.write_string(3, &self.desc)?; } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } if !self.ext_data.is_empty() { @@ -1200,7 +1200,7 @@ impl ::protobuf::Clear for CreateViewPayload { self.name.clear(); self.desc.clear(); self.one_of_thumbnail = ::std::option::Option::None; - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; self.ext_data.clear(); self.plugin_type = 0; self.unknown_fields.clear(); @@ -1358,7 +1358,7 @@ impl CreateViewParams { self.data_type } pub fn clear_data_type(&mut self) { - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; } // Param is passed by value, moved @@ -1524,7 +1524,7 @@ impl ::protobuf::Message for CreateViewParams { if !self.thumbnail.is_empty() { my_size += ::protobuf::rt::string_size(4, &self.thumbnail); } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } if !self.ext_data.is_empty() { @@ -1557,7 +1557,7 @@ impl ::protobuf::Message for CreateViewParams { if !self.thumbnail.is_empty() { os.write_string(4, &self.thumbnail)?; } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } if !self.ext_data.is_empty() { @@ -1675,7 +1675,7 @@ impl ::protobuf::Clear for CreateViewParams { self.name.clear(); self.desc.clear(); self.thumbnail.clear(); - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; self.ext_data.clear(); self.view_id.clear(); self.data.clear(); @@ -2821,7 +2821,7 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams { #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum ViewDataType { - Block = 0, + TextBlock = 0, Grid = 1, } @@ -2832,7 +2832,7 @@ impl ::protobuf::ProtobufEnum for ViewDataType { fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(ViewDataType::Block), + 0 => ::std::option::Option::Some(ViewDataType::TextBlock), 1 => ::std::option::Option::Some(ViewDataType::Grid), _ => ::std::option::Option::None } @@ -2840,7 +2840,7 @@ impl ::protobuf::ProtobufEnum for ViewDataType { fn values() -> &'static [Self] { static values: &'static [ViewDataType] = &[ - ViewDataType::Block, + ViewDataType::TextBlock, ViewDataType::Grid, ]; values @@ -2859,7 +2859,7 @@ impl ::std::marker::Copy for ViewDataType { impl ::std::default::Default for ViewDataType { fn default() -> Self { - ViewDataType::Block + ViewDataType::TextBlock } } @@ -2904,8 +2904,8 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\ \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ \x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\ - \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*#\n\x0cVi\ - ewDataType\x12\t\n\x05Block\x10\0\x12\x08\n\x04Grid\x10\x01b\x06proto3\ + \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*'\n\x0cVi\ + ewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index 2a471bc53f..9d51c50263 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -56,6 +56,6 @@ message UpdateViewParams { oneof one_of_thumbnail { string thumbnail = 4; }; } enum ViewDataType { - Block = 0; + TextBlock = 0; Grid = 1; } diff --git a/shared-lib/flowy-folder-data-model/src/user_default.rs b/shared-lib/flowy-folder-data-model/src/user_default.rs index 198953a61f..ff3161d89b 100644 --- a/shared-lib/flowy-folder-data-model/src/user_default.rs +++ b/shared-lib/flowy-folder-data-model/src/user_default.rs @@ -49,7 +49,7 @@ fn create_default_view(app_id: String, time: chrono::DateTime) -> View { let view_id = uuid::Uuid::new_v4(); let name = "Read me".to_string(); let desc = "".to_string(); - let data_type = ViewDataType::Block; + let data_type = ViewDataType::TextBlock; View { id: view_id.to_string(), diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index f6691456c8..b5cdc96e31 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -30,6 +30,15 @@ pub struct GridBlock { pub row_count: i32, } +impl GridBlock { + pub fn new() -> Self { + GridBlock { + id: uuid::Uuid::new_v4().to_string(), + ..Default::default() + } + } +} + pub struct GridBlockChangeset { pub block_id: String, pub start_row_index: Option, @@ -73,9 +82,9 @@ pub struct Field { } impl Field { - pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { + pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { Self { - id: id.to_owned(), + id: uuid::Uuid::new_v4().to_string(), name: name.to_string(), desc: desc.to_string(), field_type, @@ -224,14 +233,14 @@ pub struct RowMeta { } impl RowMeta { - pub fn new(id: &str, block_id: &str, cells: Vec) -> Self { + pub fn new(block_id: &str, cells: Vec) -> Self { let cell_by_field_id = cells .into_iter() .map(|cell| (cell.id.clone(), cell)) .collect::>(); Self { - id: id.to_owned(), + id: uuid::Uuid::new_v4().to_string(), block_id: block_id.to_owned(), cell_by_field_id, height: DEFAULT_ROW_HEIGHT, diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 2d1495e811..49780e2a52 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -32,7 +32,9 @@ fn grid_default_serde_test() { } fn create_field(field_id: &str) -> Field { - Field::new(field_id, "Text Field", "", FieldType::RichText) + let mut field = Field::new("Text Field", "", FieldType::RichText); + field.id = field_id.to_string(); + field } #[allow(dead_code)] From 1e6d82c0ec158b772cf82e332705ede92c83626e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 21:06:15 +0800 Subject: [PATCH 033/179] chore: add field builder --- .../lib/protobuf/flowy-grid/protobuf.dart | 2 +- .../protobuf/flowy-grid/type_options.pb.dart | 458 ++++++++++++++++++ .../flowy-grid/type_options.pbenum.dart | 62 +++ .../flowy-grid/type_options.pbjson.dart | 125 +++++ .../flowy-grid/type_options.pbserver.dart | 9 + frontend/rust-lib/Cargo.lock | 2 + frontend/rust-lib/flowy-block/src/editor.rs | 14 +- frontend/rust-lib/flowy-block/src/queue.rs | 6 +- .../flowy-block/tests/document/mod.rs | 4 +- .../document/{edit_script.rs => script.rs} | 10 +- .../{document_test.rs => text_block_test.rs} | 34 +- .../src/services/folder_editor.rs | 2 +- .../tests/workspace/folder_test.rs | 17 +- .../flowy-folder/tests/workspace/helper.rs | 212 -------- .../flowy-folder/tests/workspace/main.rs | 1 - .../flowy-folder/tests/workspace/script.rs | 250 +++++++++- frontend/rust-lib/flowy-grid/Cargo.toml | 7 +- frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- frontend/rust-lib/flowy-grid/src/lib.rs | 1 + frontend/rust-lib/flowy-grid/src/macros.rs | 35 +- frontend/rust-lib/flowy-grid/src/manager.rs | 2 +- .../flowy-grid/src/protobuf/model/mod.rs | 4 +- .../model/{cell_data.rs => type_options.rs} | 167 +++---- .../{cell_data.proto => type_options.proto} | 8 +- .../src/services/field/cell_stringify.rs | 34 ++ .../src/services/field/field_builder.rs | 217 +++++++++ .../flowy-grid/src/services/field/mod.rs | 7 + .../{cell_data.rs => field/type_options.rs} | 175 +++---- .../flowy-grid/src/services/grid_editor.rs | 15 +- .../src/services/grid_meta_editor.rs | 2 +- .../rust-lib/flowy-grid/src/services/mod.rs | 3 +- .../flowy-grid/src/services/stringify.rs | 29 -- .../rust-lib/flowy-grid/src/services/util.rs | 10 +- frontend/rust-lib/flowy-grid/src/util.rs | 30 ++ .../flowy-grid/tests/grid/grid_test.rs | 16 + .../rust-lib/flowy-grid/tests/grid/mod.rs | 2 + .../rust-lib/flowy-grid/tests/grid/script.rs | 75 +++ .../rust-lib/flowy-grid/tests/grid_test.rs | 0 frontend/rust-lib/flowy-grid/tests/main.rs | 1 + .../flowy-sdk/src/deps_resolve/folder_deps.rs | 2 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 4 +- frontend/rust-lib/flowy-test/src/helper.rs | 19 +- .../src/client_grid/grid_builder.rs | 20 +- .../src/entities/meta.rs | 19 +- 44 files changed, 1545 insertions(+), 569 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart rename frontend/rust-lib/flowy-block/tests/document/{edit_script.rs => script.rs} (91%) rename frontend/rust-lib/flowy-block/tests/document/{document_test.rs => text_block_test.rs} (69%) delete mode 100644 frontend/rust-lib/flowy-folder/tests/workspace/helper.rs rename frontend/rust-lib/flowy-grid/src/protobuf/model/{cell_data.rs => type_options.rs} (91%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{cell_data.proto => type_options.proto} (87%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/mod.rs rename frontend/rust-lib/flowy-grid/src/services/{cell_data.rs => field/type_options.rs} (65%) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/stringify.rs create mode 100644 frontend/rust-lib/flowy-grid/src/util.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid/script.rs delete mode 100644 frontend/rust-lib/flowy-grid/tests/grid_test.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/main.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index 39a722893a..b7eb77d660 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -1,3 +1,3 @@ // Auto-generated, do not edit -export './cell_data.pb.dart'; +export './type_options.pb.dart'; export './event_map.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart new file mode 100644 index 0000000000..152eef0c74 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart @@ -0,0 +1,458 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'type_options.pbenum.dart'; + +export 'type_options.pbenum.dart'; + +class RichTextDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextDescription', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') + ..hasRequiredFields = false + ; + + RichTextDescription._() : super(); + factory RichTextDescription({ + $core.String? format, + }) { + final _result = create(); + if (format != null) { + _result.format = format; + } + return _result; + } + factory RichTextDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RichTextDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RichTextDescription clone() => RichTextDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RichTextDescription copyWith(void Function(RichTextDescription) updates) => super.copyWith((message) => updates(message as RichTextDescription)) as RichTextDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RichTextDescription create() => RichTextDescription._(); + RichTextDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RichTextDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RichTextDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get format => $_getSZ(0); + @$pb.TagNumber(1) + set format($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFormat() => $_has(0); + @$pb.TagNumber(1) + void clearFormat() => clearField(1); +} + +class CheckboxDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxDescription', createEmptyInstance: create) + ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') + ..hasRequiredFields = false + ; + + CheckboxDescription._() : super(); + factory CheckboxDescription({ + $core.bool? isSelected, + }) { + final _result = create(); + if (isSelected != null) { + _result.isSelected = isSelected; + } + return _result; + } + factory CheckboxDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CheckboxDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CheckboxDescription clone() => CheckboxDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CheckboxDescription copyWith(void Function(CheckboxDescription) updates) => super.copyWith((message) => updates(message as CheckboxDescription)) as CheckboxDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CheckboxDescription create() => CheckboxDescription._(); + CheckboxDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CheckboxDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CheckboxDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get isSelected => $_getBF(0); + @$pb.TagNumber(1) + set isSelected($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasIsSelected() => $_has(0); + @$pb.TagNumber(1) + void clearIsSelected() => clearField(1); +} + +class DateDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values) + ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values) + ..hasRequiredFields = false + ; + + DateDescription._() : super(); + factory DateDescription({ + DateFormat? dateFormat, + TimeFormat? timeFormat, + }) { + final _result = create(); + if (dateFormat != null) { + _result.dateFormat = dateFormat; + } + if (timeFormat != null) { + _result.timeFormat = timeFormat; + } + return _result; + } + factory DateDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DateDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + DateDescription clone() => DateDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DateDescription copyWith(void Function(DateDescription) updates) => super.copyWith((message) => updates(message as DateDescription)) as DateDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static DateDescription create() => DateDescription._(); + DateDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DateDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DateDescription? _defaultInstance; + + @$pb.TagNumber(1) + DateFormat get dateFormat => $_getN(0); + @$pb.TagNumber(1) + set dateFormat(DateFormat v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasDateFormat() => $_has(0); + @$pb.TagNumber(1) + void clearDateFormat() => clearField(1); + + @$pb.TagNumber(2) + TimeFormat get timeFormat => $_getN(1); + @$pb.TagNumber(2) + set timeFormat(TimeFormat v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTimeFormat() => $_has(1); + @$pb.TagNumber(2) + void clearTimeFormat() => clearField(2); +} + +class SingleSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + SingleSelectDescription._() : super(); + factory SingleSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory SingleSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SingleSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SingleSelectDescription clone() => SingleSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SingleSelectDescription copyWith(void Function(SingleSelectDescription) updates) => super.copyWith((message) => updates(message as SingleSelectDescription)) as SingleSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SingleSelectDescription create() => SingleSelectDescription._(); + SingleSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SingleSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SingleSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class MultiSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + MultiSelectDescription._() : super(); + factory MultiSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory MultiSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MultiSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MultiSelectDescription clone() => MultiSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MultiSelectDescription copyWith(void Function(MultiSelectDescription) updates) => super.copyWith((message) => updates(message as MultiSelectDescription)) as MultiSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MultiSelectDescription create() => MultiSelectDescription._(); + MultiSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MultiSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MultiSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class SelectOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') + ..hasRequiredFields = false + ; + + SelectOption._() : super(); + factory SelectOption({ + $core.String? id, + $core.String? name, + $core.String? color, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (color != null) { + _result.color = color; + } + return _result; + } + factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SelectOption clone() => SelectOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOption create() => SelectOption._(); + SelectOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get color => $_getSZ(2); + @$pb.TagNumber(3) + set color($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasColor() => $_has(2); + @$pb.TagNumber(3) + void clearColor() => clearField(3); +} + +class NumberDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..hasRequiredFields = false + ; + + NumberDescription._() : super(); + factory NumberDescription({ + MoneySymbol? money, + $core.int? scale, + $core.String? symbol, + $core.bool? signPositive, + $core.String? name, + }) { + final _result = create(); + if (money != null) { + _result.money = money; + } + if (scale != null) { + _result.scale = scale; + } + if (symbol != null) { + _result.symbol = symbol; + } + if (signPositive != null) { + _result.signPositive = signPositive; + } + if (name != null) { + _result.name = name; + } + return _result; + } + factory NumberDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NumberDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NumberDescription clone() => NumberDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NumberDescription copyWith(void Function(NumberDescription) updates) => super.copyWith((message) => updates(message as NumberDescription)) as NumberDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NumberDescription create() => NumberDescription._(); + NumberDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NumberDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NumberDescription? _defaultInstance; + + @$pb.TagNumber(1) + MoneySymbol get money => $_getN(0); + @$pb.TagNumber(1) + set money(MoneySymbol v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasMoney() => $_has(0); + @$pb.TagNumber(1) + void clearMoney() => clearField(1); + + @$pb.TagNumber(2) + $core.int get scale => $_getIZ(1); + @$pb.TagNumber(2) + set scale($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasScale() => $_has(1); + @$pb.TagNumber(2) + void clearScale() => clearField(2); + + @$pb.TagNumber(3) + $core.String get symbol => $_getSZ(2); + @$pb.TagNumber(3) + set symbol($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasSymbol() => $_has(2); + @$pb.TagNumber(3) + void clearSymbol() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get signPositive => $_getBF(3); + @$pb.TagNumber(4) + set signPositive($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasSignPositive() => $_has(3); + @$pb.TagNumber(4) + void clearSignPositive() => clearField(4); + + @$pb.TagNumber(5) + $core.String get name => $_getSZ(4); + @$pb.TagNumber(5) + set name($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasName() => $_has(4); + @$pb.TagNumber(5) + void clearName() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart new file mode 100644 index 0000000000..c3815cf5e1 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart @@ -0,0 +1,62 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class DateFormat extends $pb.ProtobufEnum { + static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); + static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); + static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); + static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); + + static const $core.List values = [ + Local, + US, + ISO, + Friendly, + ]; + + static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static DateFormat? valueOf($core.int value) => _byValue[value]; + + const DateFormat._($core.int v, $core.String n) : super(v, n); +} + +class TimeFormat extends $pb.ProtobufEnum { + static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); + static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); + + static const $core.List values = [ + TwelveHour, + TwentyFourHour, + ]; + + static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static TimeFormat? valueOf($core.int value) => _byValue[value]; + + const TimeFormat._($core.int v, $core.String n) : super(v, n); +} + +class MoneySymbol extends $pb.ProtobufEnum { + static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + + static const $core.List values = [ + CNY, + EUR, + USD, + ]; + + static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); + static MoneySymbol? valueOf($core.int value) => _byValue[value]; + + const MoneySymbol._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart new file mode 100644 index 0000000000..71e0cf884b --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart @@ -0,0 +1,125 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use dateFormatDescriptor instead') +const DateFormat$json = const { + '1': 'DateFormat', + '2': const [ + const {'1': 'Local', '2': 0}, + const {'1': 'US', '2': 1}, + const {'1': 'ISO', '2': 2}, + const {'1': 'Friendly', '2': 3}, + ], +}; + +/// Descriptor for `DateFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List dateFormatDescriptor = $convert.base64Decode('CgpEYXRlRm9ybWF0EgkKBUxvY2FsEAASBgoCVVMQARIHCgNJU08QAhIMCghGcmllbmRseRAD'); +@$core.Deprecated('Use timeFormatDescriptor instead') +const TimeFormat$json = const { + '1': 'TimeFormat', + '2': const [ + const {'1': 'TwelveHour', '2': 0}, + const {'1': 'TwentyFourHour', '2': 1}, + ], +}; + +/// Descriptor for `TimeFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List timeFormatDescriptor = $convert.base64Decode('CgpUaW1lRm9ybWF0Eg4KClR3ZWx2ZUhvdXIQABISCg5Ud2VudHlGb3VySG91chAB'); +@$core.Deprecated('Use moneySymbolDescriptor instead') +const MoneySymbol$json = const { + '1': 'MoneySymbol', + '2': const [ + const {'1': 'CNY', '2': 0}, + const {'1': 'EUR', '2': 1}, + const {'1': 'USD', '2': 2}, + ], +}; + +/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); +@$core.Deprecated('Use richTextDescriptionDescriptor instead') +const RichTextDescription$json = const { + '1': 'RichTextDescription', + '2': const [ + const {'1': 'format', '3': 1, '4': 1, '5': 9, '10': 'format'}, + ], +}; + +/// Descriptor for `RichTextDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List richTextDescriptionDescriptor = $convert.base64Decode('ChNSaWNoVGV4dERlc2NyaXB0aW9uEhYKBmZvcm1hdBgBIAEoCVIGZm9ybWF0'); +@$core.Deprecated('Use checkboxDescriptionDescriptor instead') +const CheckboxDescription$json = const { + '1': 'CheckboxDescription', + '2': const [ + const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, + ], +}; + +/// Descriptor for `CheckboxDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List checkboxDescriptionDescriptor = $convert.base64Decode('ChNDaGVja2JveERlc2NyaXB0aW9uEh8KC2lzX3NlbGVjdGVkGAEgASgIUgppc1NlbGVjdGVk'); +@$core.Deprecated('Use dateDescriptionDescriptor instead') +const DateDescription$json = const { + '1': 'DateDescription', + '2': const [ + const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'}, + const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'}, + ], +}; + +/// Descriptor for `DateDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List dateDescriptionDescriptor = $convert.base64Decode('Cg9EYXRlRGVzY3JpcHRpb24SLAoLZGF0ZV9mb3JtYXQYASABKA4yCy5EYXRlRm9ybWF0UgpkYXRlRm9ybWF0EiwKC3RpbWVfZm9ybWF0GAIgASgOMgsuVGltZUZvcm1hdFIKdGltZUZvcm1hdA=='); +@$core.Deprecated('Use singleSelectDescriptionDescriptor instead') +const SingleSelectDescription$json = const { + '1': 'SingleSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `SingleSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List singleSelectDescriptionDescriptor = $convert.base64Decode('ChdTaW5nbGVTZWxlY3REZXNjcmlwdGlvbhInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); +@$core.Deprecated('Use multiSelectDescriptionDescriptor instead') +const MultiSelectDescription$json = const { + '1': 'MultiSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `MultiSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List multiSelectDescriptionDescriptor = $convert.base64Decode('ChZNdWx0aVNlbGVjdERlc2NyaXB0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); +@$core.Deprecated('Use selectOptionDescriptor instead') +const SelectOption$json = const { + '1': 'SelectOption', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, + ], +}; + +/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); +@$core.Deprecated('Use numberDescriptionDescriptor instead') +const NumberDescription$json = const { + '1': 'NumberDescription', + '2': const [ + const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, + const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, + const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, + const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, + const {'1': 'name', '3': 5, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart new file mode 100644 index 0000000000..b46de00bf5 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'type_options.pb.dart'; + diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 6b22e06e0a..5ae075afa3 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1059,8 +1059,10 @@ dependencies = [ "flowy-database", "flowy-derive", "flowy-error", + "flowy-grid", "flowy-grid-data-model", "flowy-sync", + "flowy-test", "lazy_static", "lib-dispatch", "lib-infra", diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs index b5e9e81810..8622c60730 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -39,7 +39,7 @@ impl ClientTextBlockEditor { rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { - let document_info = rev_manager.load::(cloud_service).await?; + let document_info = rev_manager.load::(Some(cloud_service)).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); @@ -191,17 +191,9 @@ fn spawn_edit_queue( #[cfg(feature = "flowy_unit_test")] impl ClientTextBlockEditor { - pub async fn doc_json(&self) -> FlowyResult { - let (ret, rx) = oneshot::channel::>(); - let msg = EditorCommand::ReadDeltaStr { ret }; - let _ = self.edit_cmd_tx.send(msg).await; - let s = rx.await.map_err(internal_error)??; - Ok(s) - } - - pub async fn doc_delta(&self) -> FlowyResult { + pub async fn text_block_delta(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); - let msg = EditorCommand::ReadBlockDelta { ret }; + let msg = EditorCommand::ReadDelta { ret }; let _ = self.edit_cmd_tx.send(msg).await; let delta = rx.await.map_err(internal_error)??; Ok(delta) diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 087ed9d189..94955f38d8 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -166,7 +166,7 @@ impl EditBlockQueue { let data = self.document.read().await.delta_str(); let _ = ret.send(Ok(data)); } - EditorCommand::ReadBlockDelta { ret } => { + EditorCommand::ReadDelta { ret } => { let delta = self.document.read().await.delta().clone(); let _ = ret.send(Ok(delta)); } @@ -256,7 +256,7 @@ pub(crate) enum EditorCommand { ret: Ret, }, #[allow(dead_code)] - ReadBlockDelta { + ReadDelta { ret: Ret, }, } @@ -277,7 +277,7 @@ impl std::fmt::Debug for EditorCommand { EditorCommand::Undo { .. } => "Undo", EditorCommand::Redo { .. } => "Redo", EditorCommand::ReadDeltaStr { .. } => "ReadDeltaStr", - EditorCommand::ReadBlockDelta { .. } => "ReadDocumentAsDelta", + EditorCommand::ReadDelta { .. } => "ReadDocumentAsDelta", }; f.write_str(s) } diff --git a/frontend/rust-lib/flowy-block/tests/document/mod.rs b/frontend/rust-lib/flowy-block/tests/document/mod.rs index 252787043a..8aa4c774ed 100644 --- a/frontend/rust-lib/flowy-block/tests/document/mod.rs +++ b/frontend/rust-lib/flowy-block/tests/document/mod.rs @@ -1,2 +1,2 @@ -mod document_test; -mod edit_script; +mod script; +mod text_block_test; diff --git a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs b/frontend/rust-lib/flowy-block/tests/document/script.rs similarity index 91% rename from frontend/rust-lib/flowy-block/tests/document/edit_script.rs rename to frontend/rust-lib/flowy-block/tests/document/script.rs index c30ccd8d46..87f52a3e46 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/script.rs @@ -17,16 +17,16 @@ pub enum EditorScript { AssertJson(&'static str), } -pub struct EditorTest { +pub struct TextBlockEditorTest { pub sdk: FlowySDKTest, pub editor: Arc, } -impl EditorTest { +impl TextBlockEditorTest { pub async fn new() -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new(&sdk).await; + let test = ViewTest::new_grid_view(&sdk).await; let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } @@ -41,8 +41,6 @@ impl EditorTest { let rev_manager = self.editor.rev_manager(); let cache = rev_manager.revision_cache().await; let _user_id = self.sdk.user_session.user_id().unwrap(); - // let ws_manager = self.sdk.ws_conn.clone(); - // let token = self.sdk.user_session.token().unwrap(); match script { EditorScript::InsertText(s, offset) => { @@ -74,7 +72,7 @@ impl EditorTest { } EditorScript::AssertJson(expected) => { let expected_delta: RichTextDelta = serde_json::from_str(expected).unwrap(); - let delta = self.editor.doc_delta().await.unwrap(); + let delta = self.editor.text_block_delta().await.unwrap(); if expected_delta != delta { eprintln!("✅ expect: {}", expected,); eprintln!("❌ receive: {}", delta.to_delta_str()); diff --git a/frontend/rust-lib/flowy-block/tests/document/document_test.rs b/frontend/rust-lib/flowy-block/tests/document/text_block_test.rs similarity index 69% rename from frontend/rust-lib/flowy-block/tests/document/document_test.rs rename to frontend/rust-lib/flowy-block/tests/document/text_block_test.rs index df2282d01f..93fb957cdb 100644 --- a/frontend/rust-lib/flowy-block/tests/document/document_test.rs +++ b/frontend/rust-lib/flowy-block/tests/document/text_block_test.rs @@ -1,9 +1,9 @@ -use crate::document::edit_script::{EditorScript::*, *}; +use crate::document::script::{EditorScript::*, *}; use flowy_sync::disk::RevisionState; use lib_ot::core::{count_utf16_code_units, Interval}; #[tokio::test] -async fn document_sync_current_rev_id_check() { +async fn text_block_sync_current_rev_id_check() { let scripts = vec![ InsertText("1", 0), AssertCurrentRevId(1), @@ -14,11 +14,11 @@ async fn document_sync_current_rev_id_check() { AssertNextSyncRevId(None), AssertJson(r#"[{"insert":"123\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_state_check() { +async fn text_block_sync_state_check() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -28,11 +28,11 @@ async fn document_sync_state_check() { AssertRevisionState(3, RevisionState::Ack), AssertJson(r#"[{"insert":"123\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_insert_test() { +async fn text_block_sync_insert_test() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -40,11 +40,11 @@ async fn document_sync_insert_test() { AssertJson(r#"[{"insert":"123\n"}]"#), AssertNextSyncRevId(None), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_insert_in_chinese() { +async fn text_block_sync_insert_in_chinese() { let s = "好".to_owned(); let offset = count_utf16_code_units(&s); let scripts = vec![ @@ -52,11 +52,11 @@ async fn document_sync_insert_in_chinese() { InsertText("好", offset), AssertJson(r#"[{"insert":"你好\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_insert_with_emoji() { +async fn text_block_sync_insert_with_emoji() { let s = "😁".to_owned(); let offset = count_utf16_code_units(&s); let scripts = vec![ @@ -64,11 +64,11 @@ async fn document_sync_insert_with_emoji() { InsertText("☺️", offset), AssertJson(r#"[{"insert":"😁☺️\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_delete_in_english() { +async fn text_block_sync_delete_in_english() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -76,11 +76,11 @@ async fn document_sync_delete_in_english() { Delete(Interval::new(0, 2)), AssertJson(r#"[{"insert":"3\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_delete_in_chinese() { +async fn text_block_sync_delete_in_chinese() { let s = "好".to_owned(); let offset = count_utf16_code_units(&s); let scripts = vec![ @@ -89,11 +89,11 @@ async fn document_sync_delete_in_chinese() { Delete(Interval::new(0, offset)), AssertJson(r#"[{"insert":"好\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_replace_test() { +async fn text_block_sync_replace_test() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -101,5 +101,5 @@ async fn document_sync_replace_test() { Replace(Interval::new(0, 3), "abc"), AssertJson(r#"[{"insert":"abc\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs index 0a5dd7f794..7aaa1de7cd 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -38,7 +38,7 @@ impl ClientFolderEditor { let cloud = Arc::new(FolderRevisionCloudService { token: token.to_string(), }); - let folder = Arc::new(RwLock::new(rev_manager.load::(cloud).await?)); + let folder = Arc::new(RwLock::new(rev_manager.load::(Some(cloud)).await?)); let rev_manager = Arc::new(rev_manager); let ws_manager = make_folder_ws_manager( user_id, diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs index 7dd5b66e2f..9f9bae4a82 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,6 +1,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; use flowy_folder::entities::workspace::CreateWorkspacePayload; +use flowy_folder_data_model::entities::view::ViewDataType; use flowy_sync::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; @@ -136,10 +137,12 @@ async fn app_create_with_view() { CreateView { name: "View A".to_owned(), desc: "View A description".to_owned(), + data_type: ViewDataType::TextBlock, }, CreateView { - name: "View B".to_owned(), - desc: "View B description".to_owned(), + name: "Grid".to_owned(), + desc: "Grid description".to_owned(), + data_type: ViewDataType::Grid, }, ReadApp(app.id), ]) @@ -148,7 +151,7 @@ async fn app_create_with_view() { app = test.app.clone(); assert_eq!(app.belongings.len(), 3); assert_eq!(app.belongings[1].name, "View A"); - assert_eq!(app.belongings[2].name, "View B") + assert_eq!(app.belongings[2].name, "Grid") } #[tokio::test] @@ -198,10 +201,12 @@ async fn view_delete_all() { CreateView { name: "View A".to_owned(), desc: "View A description".to_owned(), + data_type: ViewDataType::TextBlock, }, CreateView { - name: "View B".to_owned(), - desc: "View B description".to_owned(), + name: "Grid".to_owned(), + desc: "Grid description".to_owned(), + data_type: ViewDataType::Grid, }, ReadApp(app.id.clone()), ]) @@ -229,6 +234,7 @@ async fn view_delete_all_permanent() { CreateView { name: "View A".to_owned(), desc: "View A description".to_owned(), + data_type: ViewDataType::TextBlock, }, ReadApp(app.id.clone()), ]) @@ -327,6 +333,7 @@ async fn folder_sync_revision_with_new_view() { CreateView { name: view_name.clone(), desc: view_desc.clone(), + data_type: ViewDataType::TextBlock, }, AssertCurrentRevId(3), AssertNextSyncRevId(Some(3)), diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs deleted file mode 100644 index 93e2ff2b7f..0000000000 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ /dev/null @@ -1,212 +0,0 @@ -use flowy_collaboration::entities::text_block_info::TextBlockInfo; -use flowy_folder::event_map::FolderEvent::*; -use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; -use flowy_folder_data_model::entities::workspace::WorkspaceId; -use flowy_folder_data_model::entities::{ - app::{App, AppId, CreateAppPayload, UpdateAppPayload}, - trash::{RepeatedTrash, TrashId, TrashType}, - view::{CreateViewPayload, UpdateViewPayload, View, ViewDataType}, - workspace::{CreateWorkspacePayload, RepeatedWorkspace, Workspace}, -}; -use flowy_test::{event_builder::*, FlowySDKTest}; - -pub async fn create_workspace(sdk: &FlowySDKTest, name: &str, desc: &str) -> Workspace { - let request = CreateWorkspacePayload { - name: name.to_owned(), - desc: desc.to_owned(), - }; - - let workspace = FolderEventBuilder::new(sdk.clone()) - .event(CreateWorkspace) - .payload(request) - .async_send() - .await - .parse::(); - workspace -} - -pub async fn read_workspace(sdk: &FlowySDKTest, workspace_id: Option) -> Vec { - let request = WorkspaceId { value: workspace_id }; - let repeated_workspace = FolderEventBuilder::new(sdk.clone()) - .event(ReadWorkspaces) - .payload(request.clone()) - .async_send() - .await - .parse::(); - - let workspaces; - if let Some(workspace_id) = &request.value { - workspaces = repeated_workspace - .into_inner() - .into_iter() - .filter(|workspace| &workspace.id == workspace_id) - .collect::>(); - debug_assert_eq!(workspaces.len(), 1); - } else { - workspaces = repeated_workspace.items; - } - - workspaces -} - -pub async fn create_app(sdk: &FlowySDKTest, workspace_id: &str, name: &str, desc: &str) -> App { - let create_app_request = CreateAppPayload { - workspace_id: workspace_id.to_owned(), - name: name.to_string(), - desc: desc.to_string(), - color_style: Default::default(), - }; - - let app = FolderEventBuilder::new(sdk.clone()) - .event(CreateApp) - .payload(create_app_request) - .async_send() - .await - .parse::(); - app -} - -pub async fn read_app(sdk: &FlowySDKTest, app_id: &str) -> App { - let request = AppId { - value: app_id.to_owned(), - }; - - let app = FolderEventBuilder::new(sdk.clone()) - .event(ReadApp) - .payload(request) - .async_send() - .await - .parse::(); - - app -} - -pub async fn update_app(sdk: &FlowySDKTest, app_id: &str, name: Option, desc: Option) { - let request = UpdateAppPayload { - app_id: app_id.to_string(), - name, - desc, - color_style: None, - is_trash: None, - }; - - FolderEventBuilder::new(sdk.clone()) - .event(UpdateApp) - .payload(request) - .async_send() - .await; -} - -pub async fn delete_app(sdk: &FlowySDKTest, app_id: &str) { - let request = AppId { - value: app_id.to_string(), - }; - - FolderEventBuilder::new(sdk.clone()) - .event(DeleteApp) - .payload(request) - .async_send() - .await; -} - -pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &str, data_type: ViewDataType) -> View { - let request = CreateViewPayload { - belong_to_id: app_id.to_string(), - name: name.to_string(), - desc: desc.to_string(), - thumbnail: None, - data_type, - ext_data: "".to_string(), - plugin_type: 0, - }; - let view = FolderEventBuilder::new(sdk.clone()) - .event(CreateView) - .payload(request) - .async_send() - .await - .parse::(); - view -} - -pub async fn read_view(sdk: &FlowySDKTest, view_id: &str) -> View { - let view_id: ViewId = view_id.into(); - FolderEventBuilder::new(sdk.clone()) - .event(ReadView) - .payload(view_id) - .async_send() - .await - .parse::() -} - -pub async fn update_view(sdk: &FlowySDKTest, view_id: &str, name: Option, desc: Option) { - let request = UpdateViewPayload { - view_id: view_id.to_string(), - name, - desc, - thumbnail: None, - }; - FolderEventBuilder::new(sdk.clone()) - .event(UpdateView) - .payload(request) - .async_send() - .await; -} - -pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { - let request = RepeatedViewId { items: view_ids }; - FolderEventBuilder::new(sdk.clone()) - .event(DeleteView) - .payload(request) - .async_send() - .await; -} - -#[allow(dead_code)] -pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { - let view_id: ViewId = view_id.into(); - FolderEventBuilder::new(sdk.clone()) - .event(SetLatestView) - .payload(view_id) - .async_send() - .await - .parse::() -} - -pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { - FolderEventBuilder::new(sdk.clone()) - .event(ReadTrash) - .async_send() - .await - .parse::() -} - -pub async fn restore_app_from_trash(sdk: &FlowySDKTest, app_id: &str) { - let id = TrashId { - id: app_id.to_owned(), - ty: TrashType::TrashApp, - }; - FolderEventBuilder::new(sdk.clone()) - .event(PutbackTrash) - .payload(id) - .async_send() - .await; -} - -pub async fn restore_view_from_trash(sdk: &FlowySDKTest, view_id: &str) { - let id = TrashId { - id: view_id.to_owned(), - ty: TrashType::TrashView, - }; - FolderEventBuilder::new(sdk.clone()) - .event(PutbackTrash) - .payload(id) - .async_send() - .await; -} - -pub async fn delete_all_trash(sdk: &FlowySDKTest) { - FolderEventBuilder::new(sdk.clone()) - .event(DeleteAllTrash) - .async_send() - .await; -} diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/main.rs b/frontend/rust-lib/flowy-folder/tests/workspace/main.rs index 553449ee4b..ff48b349e1 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/main.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/main.rs @@ -1,3 +1,2 @@ mod folder_test; -mod helper; mod script; diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 7674ca0a54..9c2c8ecbed 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -1,39 +1,63 @@ -use crate::helper::*; - +use flowy_collaboration::entities::text_block_info::TextBlockInfo; +use flowy_folder::event_map::FolderEvent::*; use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; +use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; +use flowy_folder_data_model::entities::workspace::WorkspaceId; use flowy_folder_data_model::entities::{ app::{App, RepeatedApp}, trash::Trash, view::{RepeatedView, View, ViewDataType}, workspace::Workspace, }; +use flowy_folder_data_model::entities::{ + app::{AppId, CreateAppPayload, UpdateAppPayload}, + trash::{RepeatedTrash, TrashId, TrashType}, + view::{CreateViewPayload, UpdateViewPayload}, + workspace::{CreateWorkspacePayload, RepeatedWorkspace}, +}; use flowy_sync::disk::RevisionState; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; -use flowy_test::FlowySDKTest; +use flowy_test::{event_builder::*, FlowySDKTest}; use std::{sync::Arc, time::Duration}; use tokio::time::sleep; pub enum FolderScript { // Workspace ReadAllWorkspaces, - CreateWorkspace { name: String, desc: String }, + CreateWorkspace { + name: String, + desc: String, + }, AssertWorkspaceJson(String), AssertWorkspace(Workspace), ReadWorkspace(Option), // App - CreateApp { name: String, desc: String }, + CreateApp { + name: String, + desc: String, + }, AssertAppJson(String), AssertApp(App), ReadApp(String), - UpdateApp { name: Option, desc: Option }, + UpdateApp { + name: Option, + desc: Option, + }, DeleteApp, // View - CreateView { name: String, desc: String }, + CreateView { + name: String, + desc: String, + data_type: ViewDataType, + }, AssertView(View), ReadView(String), - UpdateView { name: Option, desc: Option }, + UpdateView { + name: Option, + desc: Option, + }, DeleteView, DeleteViews(Vec), @@ -46,7 +70,10 @@ pub enum FolderScript { // Sync AssertCurrentRevId(i64), AssertNextSyncRevId(Option), - AssertRevisionState { rev_id: i64, state: RevisionState }, + AssertRevisionState { + rev_id: i64, + state: RevisionState, + }, } pub struct FolderTest { @@ -148,8 +175,8 @@ impl FolderTest { delete_app(sdk, &self.app.id).await; } - FolderScript::CreateView { name, desc } => { - let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::TextBlock).await; + FolderScript::CreateView { name, desc, data_type } => { + let view = create_view(sdk, &self.app.id, &name, &desc, data_type).await; self.view = view; } FolderScript::AssertView(view) => { @@ -216,3 +243,204 @@ pub fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> { ("1234".repeat(100), ErrorCode::WorkspaceNameTooLong), ] } + +pub async fn create_workspace(sdk: &FlowySDKTest, name: &str, desc: &str) -> Workspace { + let request = CreateWorkspacePayload { + name: name.to_owned(), + desc: desc.to_owned(), + }; + + let workspace = FolderEventBuilder::new(sdk.clone()) + .event(CreateWorkspace) + .payload(request) + .async_send() + .await + .parse::(); + workspace +} + +pub async fn read_workspace(sdk: &FlowySDKTest, workspace_id: Option) -> Vec { + let request = WorkspaceId { value: workspace_id }; + let repeated_workspace = FolderEventBuilder::new(sdk.clone()) + .event(ReadWorkspaces) + .payload(request.clone()) + .async_send() + .await + .parse::(); + + let workspaces; + if let Some(workspace_id) = &request.value { + workspaces = repeated_workspace + .into_inner() + .into_iter() + .filter(|workspace| &workspace.id == workspace_id) + .collect::>(); + debug_assert_eq!(workspaces.len(), 1); + } else { + workspaces = repeated_workspace.items; + } + + workspaces +} + +pub async fn create_app(sdk: &FlowySDKTest, workspace_id: &str, name: &str, desc: &str) -> App { + let create_app_request = CreateAppPayload { + workspace_id: workspace_id.to_owned(), + name: name.to_string(), + desc: desc.to_string(), + color_style: Default::default(), + }; + + let app = FolderEventBuilder::new(sdk.clone()) + .event(CreateApp) + .payload(create_app_request) + .async_send() + .await + .parse::(); + app +} + +pub async fn read_app(sdk: &FlowySDKTest, app_id: &str) -> App { + let request = AppId { + value: app_id.to_owned(), + }; + + let app = FolderEventBuilder::new(sdk.clone()) + .event(ReadApp) + .payload(request) + .async_send() + .await + .parse::(); + + app +} + +pub async fn update_app(sdk: &FlowySDKTest, app_id: &str, name: Option, desc: Option) { + let request = UpdateAppPayload { + app_id: app_id.to_string(), + name, + desc, + color_style: None, + is_trash: None, + }; + + FolderEventBuilder::new(sdk.clone()) + .event(UpdateApp) + .payload(request) + .async_send() + .await; +} + +pub async fn delete_app(sdk: &FlowySDKTest, app_id: &str) { + let request = AppId { + value: app_id.to_string(), + }; + + FolderEventBuilder::new(sdk.clone()) + .event(DeleteApp) + .payload(request) + .async_send() + .await; +} + +pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &str, data_type: ViewDataType) -> View { + let request = CreateViewPayload { + belong_to_id: app_id.to_string(), + name: name.to_string(), + desc: desc.to_string(), + thumbnail: None, + data_type, + ext_data: "".to_string(), + plugin_type: 0, + }; + let view = FolderEventBuilder::new(sdk.clone()) + .event(CreateView) + .payload(request) + .async_send() + .await + .parse::(); + view +} + +pub async fn read_view(sdk: &FlowySDKTest, view_id: &str) -> View { + let view_id: ViewId = view_id.into(); + FolderEventBuilder::new(sdk.clone()) + .event(ReadView) + .payload(view_id) + .async_send() + .await + .parse::() +} + +pub async fn update_view(sdk: &FlowySDKTest, view_id: &str, name: Option, desc: Option) { + let request = UpdateViewPayload { + view_id: view_id.to_string(), + name, + desc, + thumbnail: None, + }; + FolderEventBuilder::new(sdk.clone()) + .event(UpdateView) + .payload(request) + .async_send() + .await; +} + +pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { + let request = RepeatedViewId { items: view_ids }; + FolderEventBuilder::new(sdk.clone()) + .event(DeleteView) + .payload(request) + .async_send() + .await; +} + +#[allow(dead_code)] +pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { + let view_id: ViewId = view_id.into(); + FolderEventBuilder::new(sdk.clone()) + .event(SetLatestView) + .payload(view_id) + .async_send() + .await + .parse::() +} + +pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { + FolderEventBuilder::new(sdk.clone()) + .event(ReadTrash) + .async_send() + .await + .parse::() +} + +pub async fn restore_app_from_trash(sdk: &FlowySDKTest, app_id: &str) { + let id = TrashId { + id: app_id.to_owned(), + ty: TrashType::TrashApp, + }; + FolderEventBuilder::new(sdk.clone()) + .event(PutbackTrash) + .payload(id) + .async_send() + .await; +} + +pub async fn restore_view_from_trash(sdk: &FlowySDKTest, view_id: &str) { + let id = TrashId { + id: view_id.to_owned(), + ty: TrashType::TrashView, + }; + FolderEventBuilder::new(sdk.clone()) + .event(PutbackTrash) + .payload(id) + .async_send() + .await; +} + +pub async fn delete_all_trash(sdk: &FlowySDKTest) { + FolderEventBuilder::new(sdk.clone()) + .event(DeleteAllTrash) + .async_send() + .await; +} diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 95a5899f5e..48c7e346a4 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -34,10 +34,15 @@ tokio = {version = "1", features = ["sync"]} rayon = "1.5" parking_lot = "0.11" +[dev-dependencies] +flowy-test = { path = "../flowy-test" } +flowy-grid = { path = "../flowy-grid", features = ["flowy_unit_test"]} + [build-dependencies] lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } [features] default = [] -dart = ["lib-infra/dart"] \ No newline at end of file +dart = ["lib-infra/dart"] +flowy_unit_test = ["flowy-sync/flowy_unit_test"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index d7c3d8260d..fc5c01c773 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/cell_data.rs"] +proto_crates = ["src/event_map.rs", "src/services/field/type_options.rs"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 262fe1d1c2..526e1e4267 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -7,3 +7,4 @@ pub mod manager; mod protobuf; pub mod services; +pub mod util; diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 043dcccb44..9f2fedddc7 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -1,29 +1,17 @@ #[macro_export] -macro_rules! impl_any_data { +macro_rules! impl_from_and_to_type_option { ($target: ident, $field_type:expr) => { - impl_field_type_data_from_field!($target); - impl_field_type_data_from_field_type_option!($target); - impl_type_option_from_field_data!($target, $field_type); + impl_from_field_type_option!($target); + impl_to_field_type_option!($target, $field_type); }; } #[macro_export] -macro_rules! impl_field_type_data_from_field { +macro_rules! impl_from_field_type_option { ($target: ident) => { impl std::convert::From<&Field> for $target { fn from(field: &Field) -> $target { - $target::from(&field.type_options) - } - } - }; -} - -#[macro_export] -macro_rules! impl_field_type_data_from_field_type_option { - ($target: ident) => { - impl std::convert::From<&AnyData> for $target { - fn from(any_data: &AnyData) -> $target { - match $target::try_from(Bytes::from(any_data.value.clone())) { + match $target::try_from(Bytes::from(field.type_options.value.clone())) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); @@ -36,26 +24,27 @@ macro_rules! impl_field_type_data_from_field_type_option { } #[macro_export] -macro_rules! impl_type_option_from_field_data { +macro_rules! impl_to_field_type_option { ($target: ident, $field_type:expr) => { impl $target { - pub fn field_type() -> FieldType { + pub fn field_type(&self) -> FieldType { $field_type } } impl std::convert::From<$target> for AnyData { - fn from(field_data: $target) -> Self { - match field_data.try_into() { + fn from(field_description: $target) -> Self { + let field_type = field_description.field_type(); + match field_description.try_into() { Ok(bytes) => { let bytes: Bytes = bytes; - AnyData::from_bytes(&$target::field_type(), bytes) + AnyData::from_bytes(field_type, bytes) } Err(e) => { tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); // it's impossible to fail when unwrapping the default field type data let default_bytes: Bytes = $target::default().try_into().unwrap(); - AnyData::from_bytes(&$target::field_type(), default_bytes) + AnyData::from_bytes(field_type, default_bytes) } } } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 05e61b26ce..fc79fcf5c0 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -113,7 +113,7 @@ impl GridManager { Ok(grid_editor) } - fn make_grid_rev_manager(&self, grid_id: &str, pool: Arc) -> FlowyResult { + pub fn make_grid_rev_manager(&self, grid_id: &str, pool: Arc) -> FlowyResult { let user_id = self.grid_user.user_id()?; let disk_cache = Arc::new(SQLiteGridRevisionPersistence::new(&user_id, pool)); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index 55aeddc863..d9c75efb74 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,8 +1,8 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit -mod cell_data; -pub use cell_data::*; +mod type_options; +pub use type_options::*; mod event_map; pub use event_map::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs similarity index 91% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs index d173fe22d0..cda2c556c3 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs @@ -17,7 +17,7 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `cell_data.proto` +//! Generated file from `type_options.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. @@ -514,7 +514,7 @@ impl ::protobuf::reflect::ProtobufValue for DateDescription { } #[derive(PartialEq,Clone,Default)] -pub struct SingleSelect { +pub struct SingleSelectDescription { // message fields pub options: ::protobuf::RepeatedField, pub disable_color: bool, @@ -523,14 +523,14 @@ pub struct SingleSelect { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a SingleSelect { - fn default() -> &'a SingleSelect { - ::default_instance() +impl<'a> ::std::default::Default for &'a SingleSelectDescription { + fn default() -> &'a SingleSelectDescription { + ::default_instance() } } -impl SingleSelect { - pub fn new() -> SingleSelect { +impl SingleSelectDescription { + pub fn new() -> SingleSelectDescription { ::std::default::Default::default() } @@ -575,7 +575,7 @@ impl SingleSelect { } } -impl ::protobuf::Message for SingleSelect { +impl ::protobuf::Message for SingleSelectDescription { fn is_initialized(&self) -> bool { for v in &self.options { if !v.is_initialized() { @@ -662,8 +662,8 @@ impl ::protobuf::Message for SingleSelect { Self::descriptor_static() } - fn new() -> SingleSelect { - SingleSelect::new() + fn new() -> SingleSelectDescription { + SingleSelectDescription::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -672,29 +672,29 @@ impl ::protobuf::Message for SingleSelect { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "options", - |m: &SingleSelect| { &m.options }, - |m: &mut SingleSelect| { &mut m.options }, + |m: &SingleSelectDescription| { &m.options }, + |m: &mut SingleSelectDescription| { &mut m.options }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "disable_color", - |m: &SingleSelect| { &m.disable_color }, - |m: &mut SingleSelect| { &mut m.disable_color }, + |m: &SingleSelectDescription| { &m.disable_color }, + |m: &mut SingleSelectDescription| { &mut m.disable_color }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SingleSelect", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SingleSelectDescription", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static SingleSelect { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SingleSelect::new) + fn default_instance() -> &'static SingleSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SingleSelectDescription::new) } } -impl ::protobuf::Clear for SingleSelect { +impl ::protobuf::Clear for SingleSelectDescription { fn clear(&mut self) { self.options.clear(); self.disable_color = false; @@ -702,20 +702,20 @@ impl ::protobuf::Clear for SingleSelect { } } -impl ::std::fmt::Debug for SingleSelect { +impl ::std::fmt::Debug for SingleSelectDescription { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for SingleSelect { +impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct MultiSelect { +pub struct MultiSelectDescription { // message fields pub options: ::protobuf::RepeatedField, pub disable_color: bool, @@ -724,14 +724,14 @@ pub struct MultiSelect { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a MultiSelect { - fn default() -> &'a MultiSelect { - ::default_instance() +impl<'a> ::std::default::Default for &'a MultiSelectDescription { + fn default() -> &'a MultiSelectDescription { + ::default_instance() } } -impl MultiSelect { - pub fn new() -> MultiSelect { +impl MultiSelectDescription { + pub fn new() -> MultiSelectDescription { ::std::default::Default::default() } @@ -776,7 +776,7 @@ impl MultiSelect { } } -impl ::protobuf::Message for MultiSelect { +impl ::protobuf::Message for MultiSelectDescription { fn is_initialized(&self) -> bool { for v in &self.options { if !v.is_initialized() { @@ -863,8 +863,8 @@ impl ::protobuf::Message for MultiSelect { Self::descriptor_static() } - fn new() -> MultiSelect { - MultiSelect::new() + fn new() -> MultiSelectDescription { + MultiSelectDescription::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -873,29 +873,29 @@ impl ::protobuf::Message for MultiSelect { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "options", - |m: &MultiSelect| { &m.options }, - |m: &mut MultiSelect| { &mut m.options }, + |m: &MultiSelectDescription| { &m.options }, + |m: &mut MultiSelectDescription| { &mut m.options }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "disable_color", - |m: &MultiSelect| { &m.disable_color }, - |m: &mut MultiSelect| { &mut m.disable_color }, + |m: &MultiSelectDescription| { &m.disable_color }, + |m: &mut MultiSelectDescription| { &mut m.disable_color }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "MultiSelect", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MultiSelectDescription", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static MultiSelect { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(MultiSelect::new) + fn default_instance() -> &'static MultiSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MultiSelectDescription::new) } } -impl ::protobuf::Clear for MultiSelect { +impl ::protobuf::Clear for MultiSelectDescription { fn clear(&mut self) { self.options.clear(); self.disable_color = false; @@ -903,13 +903,13 @@ impl ::protobuf::Clear for MultiSelect { } } -impl ::std::fmt::Debug for MultiSelect { +impl ::std::fmt::Debug for MultiSelectDescription { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for MultiSelect { +impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1161,7 +1161,7 @@ impl ::protobuf::reflect::ProtobufValue for SelectOption { #[derive(PartialEq,Clone,Default)] pub struct NumberDescription { // message fields - pub money: FlowyMoney, + pub money: MoneySymbol, pub scale: u32, pub symbol: ::std::string::String, pub sign_positive: bool, @@ -1182,18 +1182,18 @@ impl NumberDescription { ::std::default::Default::default() } - // .FlowyMoney money = 1; + // .MoneySymbol money = 1; - pub fn get_money(&self) -> FlowyMoney { + pub fn get_money(&self) -> MoneySymbol { self.money } pub fn clear_money(&mut self) { - self.money = FlowyMoney::CNY; + self.money = MoneySymbol::CNY; } // Param is passed by value, moved - pub fn set_money(&mut self, v: FlowyMoney) { + pub fn set_money(&mut self, v: MoneySymbol) { self.money = v; } @@ -1324,7 +1324,7 @@ impl ::protobuf::Message for NumberDescription { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if self.money != FlowyMoney::CNY { + if self.money != MoneySymbol::CNY { my_size += ::protobuf::rt::enum_size(1, self.money); } if self.scale != 0 { @@ -1345,7 +1345,7 @@ impl ::protobuf::Message for NumberDescription { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.money != FlowyMoney::CNY { + if self.money != MoneySymbol::CNY { os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; } if self.scale != 0 { @@ -1398,7 +1398,7 @@ impl ::protobuf::Message for NumberDescription { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "money", |m: &NumberDescription| { &m.money }, |m: &mut NumberDescription| { &mut m.money }, @@ -1439,7 +1439,7 @@ impl ::protobuf::Message for NumberDescription { impl ::protobuf::Clear for NumberDescription { fn clear(&mut self) { - self.money = FlowyMoney::CNY; + self.money = MoneySymbol::CNY; self.scale = 0; self.symbol.clear(); self.sign_positive = false; @@ -1567,31 +1567,31 @@ impl ::protobuf::reflect::ProtobufValue for TimeFormat { } #[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum FlowyMoney { +pub enum MoneySymbol { CNY = 0, EUR = 1, USD = 2, } -impl ::protobuf::ProtobufEnum for FlowyMoney { +impl ::protobuf::ProtobufEnum for MoneySymbol { fn value(&self) -> i32 { *self as i32 } - fn from_i32(value: i32) -> ::std::option::Option { + fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(FlowyMoney::CNY), - 1 => ::std::option::Option::Some(FlowyMoney::EUR), - 2 => ::std::option::Option::Some(FlowyMoney::USD), + 0 => ::std::option::Option::Some(MoneySymbol::CNY), + 1 => ::std::option::Option::Some(MoneySymbol::EUR), + 2 => ::std::option::Option::Some(MoneySymbol::USD), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { - static values: &'static [FlowyMoney] = &[ - FlowyMoney::CNY, - FlowyMoney::EUR, - FlowyMoney::USD, + static values: &'static [MoneySymbol] = &[ + MoneySymbol::CNY, + MoneySymbol::EUR, + MoneySymbol::USD, ]; values } @@ -1599,47 +1599,48 @@ impl ::protobuf::ProtobufEnum for FlowyMoney { fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("FlowyMoney", file_descriptor_proto()) + ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) }) } } -impl ::std::marker::Copy for FlowyMoney { +impl ::std::marker::Copy for MoneySymbol { } -impl ::std::default::Default for FlowyMoney { +impl ::std::default::Default for MoneySymbol { fn default() -> Self { - FlowyMoney::CNY + MoneySymbol::CNY } } -impl ::protobuf::reflect::ProtobufValue for FlowyMoney { +impl ::protobuf::reflect::ProtobufValue for MoneySymbol { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fcell_data.proto\"-\n\x13RichTextDescription\x12\x16\n\x06format\ + \n\x12type_options.proto\"-\n\x13RichTextDescription\x12\x16\n\x06format\ \x18\x01\x20\x01(\tR\x06format\"6\n\x13CheckboxDescription\x12\x1f\n\x0b\ is_selected\x18\x01\x20\x01(\x08R\nisSelected\"m\n\x0fDateDescription\ \x12,\n\x0bdate_format\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\ \x12,\n\x0btime_format\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat\ - \"\\\n\x0cSingleSelect\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectO\ - ptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisable\ - Color\"[\n\x0bMultiSelect\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.Sele\ - ctOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisa\ - bleColor\"H\n\x0cSelectOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05color\x18\ - \x03\x20\x01(\tR\x05color\"\x9d\x01\n\x11NumberDescription\x12!\n\x05mon\ - ey\x18\x01\x20\x01(\x0e2\x0b.FlowyMoneyR\x05money\x12\x14\n\x05scale\x18\ - \x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\tR\x06sym\ - bol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositive\x12\x12\ - \n\x04name\x18\x05\x20\x01(\tR\x04name*6\n\nDateFormat\x12\t\n\x05Local\ - \x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\x0c\n\x08Fri\ - endly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\x12\x12\n\x0eT\ - wentyFourHour\x10\x01*'\n\nFlowyMoney\x12\x07\n\x03CNY\x10\0\x12\x07\n\ - \x03EUR\x10\x01\x12\x07\n\x03USD\x10\x02b\x06proto3\ + \"g\n\x17SingleSelectDescription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\ + \r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\ + \x0cdisableColor\"f\n\x16MultiSelectDescription\x12'\n\x07options\x18\ + \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\ + \x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cSelectOption\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\ + \x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05color\"\x9e\x01\n\x11NumberDe\ + scription\x12\"\n\x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05mon\ + ey\x12\x14\n\x05scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\ + \x18\x03\x20\x01(\tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\ + \x08R\x0csignPositive\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*6\n\ + \nDateFormat\x12\t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\ + \x03ISO\x10\x02\x12\x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\ + \nTwelveHour\x10\0\x12\x12\n\x0eTwentyFourHour\x10\x01*(\n\x0bMoneySymbo\ + l\x12\x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\ + \x02b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto similarity index 87% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto index dc146af19e..170035085c 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto @@ -10,11 +10,11 @@ message DateDescription { DateFormat date_format = 1; TimeFormat time_format = 2; } -message SingleSelect { +message SingleSelectDescription { repeated SelectOption options = 1; bool disable_color = 2; } -message MultiSelect { +message MultiSelectDescription { repeated SelectOption options = 1; bool disable_color = 2; } @@ -24,7 +24,7 @@ message SelectOption { string color = 3; } message NumberDescription { - FlowyMoney money = 1; + MoneySymbol money = 1; uint32 scale = 2; string symbol = 3; bool sign_positive = 4; @@ -40,7 +40,7 @@ enum TimeFormat { TwelveHour = 0; TwentyFourHour = 1; } -enum FlowyMoney { +enum MoneySymbol { CNY = 0; EUR = 1; USD = 2; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs new file mode 100644 index 0000000000..a75506e339 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs @@ -0,0 +1,34 @@ +use crate::services::field::*; +use crate::services::util::*; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; + +pub trait StringifyCellData { + fn str_from_cell_data(&self, data: AnyData) -> String; + fn str_to_cell_data(&self, s: &str) -> Result; +} + +#[allow(dead_code)] +pub fn stringify_serialize(field: &Field, s: &str) -> Result { + match field.field_type { + FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), + FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), + FieldType::DateTime => DateDescription::from(field).str_to_cell_data(s), + FieldType::SingleSelect => SingleSelectDescription::from(field).str_to_cell_data(s), + FieldType::MultiSelect => MultiSelectDescription::from(field).str_to_cell_data(s), + FieldType::Checkbox => CheckboxDescription::from(field).str_to_cell_data(s), + } +} + +pub(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result { + let _ = check_type_id(&data, field)?; + let s = match field.field_type { + FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), + FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), + FieldType::DateTime => DateDescription::from(field).str_from_cell_data(data), + FieldType::SingleSelect => SingleSelectDescription::from(field).str_from_cell_data(data), + FieldType::MultiSelect => MultiSelectDescription::from(field).str_from_cell_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).str_from_cell_data(data), + }; + Ok(s) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs new file mode 100644 index 0000000000..3870fc1359 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -0,0 +1,217 @@ +use crate::services::field::{ + CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, + RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, +}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; + +pub struct FieldBuilder { + field: Field, + type_options_builder: Box, +} + +impl FieldBuilder { + pub fn new(type_options_builder: T) -> Self { + let field = Field::new("Name", "", FieldType::RichText); + Self { + field, + type_options_builder: Box::new(type_options_builder), + } + } + + pub fn name(mut self, name: &str) -> Self { + self.field.name = name.to_owned(); + self + } + + pub fn desc(mut self, desc: &str) -> Self { + self.field.desc = desc.to_owned(); + self + } + + pub fn field_type(mut self, field_type: FieldType) -> Self { + self.field.field_type = field_type; + self + } + + pub fn visibility(mut self, visibility: bool) -> Self { + self.field.visibility = visibility; + self + } + + pub fn width(mut self, width: i32) -> Self { + self.field.width = width; + self + } + + pub fn frozen(mut self, frozen: bool) -> Self { + self.field.frozen = frozen; + self + } + + pub fn build(mut self) -> Field { + assert_eq!(self.field.field_type, self.type_options_builder.field_type()); + + let type_options = self.type_options_builder.build(); + self.field.type_options = type_options; + self.field + } +} + +pub trait TypeOptionsBuilder { + fn field_type(&self) -> FieldType; + fn build(&self) -> AnyData; +} + +// Text +pub struct RichTextTypeOptionsBuilder(RichTextDescription); + +impl RichTextTypeOptionsBuilder { + pub fn new() -> Self { + Self(RichTextDescription::default()) + } +} + +impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Number +pub struct NumberTypeOptionsBuilder(NumberDescription); + +impl NumberTypeOptionsBuilder { + pub fn new() -> Self { + Self(NumberDescription::default()) + } + + pub fn name(mut self, name: &str) -> Self { + self.0.name = name.to_string(); + self + } + + pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { + self.0.set_money_symbol(money_symbol); + self + } + + pub fn scale(mut self, scale: u32) -> Self { + self.0.scale = scale; + self + } + + pub fn positive(mut self, positive: bool) -> Self { + self.0.sign_positive = positive; + self + } +} + +impl TypeOptionsBuilder for NumberTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Date +pub struct DateTypeOptionsBuilder(DateDescription); +impl DateTypeOptionsBuilder { + pub fn new() -> Self { + Self(DateDescription::default()) + } + + pub fn date_format(mut self, date_format: DateFormat) -> Self { + self.0.date_format = date_format; + self + } + + pub fn time_format(mut self, time_format: TimeFormat) -> Self { + self.0.time_format = time_format; + self + } +} +impl TypeOptionsBuilder for DateTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Single Select +pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); + +impl SingleSelectTypeOptionsBuilder { + pub fn new() -> Self { + Self(SingleSelectDescription::default()) + } + + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} +impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Multi Select +pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); + +impl MultiSelectTypeOptionsBuilder { + pub fn new() -> Self { + Self(MultiSelectDescription::default()) + } + + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} + +impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Checkbox +pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); +impl CheckboxTypeOptionsBuilder { + pub fn new() -> Self { + Self(CheckboxDescription::default()) + } + + pub fn set_selected(mut self, is_selected: bool) -> Self { + self.0.is_selected = is_selected; + self + } +} +impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs new file mode 100644 index 0000000000..157e5145c2 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -0,0 +1,7 @@ +mod cell_stringify; +mod field_builder; +mod type_options; + +pub use cell_stringify::*; +pub use field_builder::*; +pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs similarity index 65% rename from frontend/rust-lib/flowy-grid/src/services/cell_data.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index ce65fb005a..1a417abe20 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -1,5 +1,6 @@ #![allow(clippy::upper_case_acronyms)] -use crate::impl_any_data; +use crate::impl_from_and_to_type_option; +use crate::services::field::StringifyCellData; use crate::services::util::*; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; @@ -15,63 +16,42 @@ use rusty_money::{ use std::str::FromStr; use strum_macros::EnumIter; -pub trait StringifyAnyData { - fn stringify_any_data(&self, data: AnyData) -> String; - fn str_to_any_data(&self, s: &str) -> Result; -} - -pub trait DisplayCell { - fn display_content(&self, s: &str) -> String; -} - #[derive(Debug, Clone, ProtoBuf, Default)] pub struct RichTextDescription { #[pb(index = 1)] pub format: String, } -impl_any_data!(RichTextDescription, FieldType::RichText); +impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); -impl StringifyAnyData for RichTextDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for RichTextDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(&RichTextDescription::field_type(), s)) - } -} - -impl DisplayCell for RichTextDescription { - fn display_content(&self, s: &str) -> String { - s.to_string() + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(AnyData::from_str(self.field_type(), s)) } } // Checkbox -#[derive(Debug, ProtoBuf, Default)] +#[derive(Debug, Clone, ProtoBuf, Default)] pub struct CheckboxDescription { #[pb(index = 1)] pub is_selected: bool, } -impl_any_data!(CheckboxDescription, FieldType::Checkbox); +impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); -impl StringifyAnyData for CheckboxDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for CheckboxDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let s = match string_to_bool(s) { true => "1", false => "0", }; - Ok(AnyData::from_str(&CheckboxDescription::field_type(), s)) - } -} - -impl DisplayCell for CheckboxDescription { - fn display_content(&self, s: &str) -> String { - s.to_string() + Ok(AnyData::from_str(self.field_type(), s)) } } @@ -84,7 +64,7 @@ pub struct DateDescription { #[pb(index = 2)] pub time_format: TimeFormat, } -impl_any_data!(DateDescription, FieldType::DateTime); +impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); impl DateDescription { fn date_time_format_str(&self) -> String { @@ -107,23 +87,8 @@ impl DateDescription { } } -impl DisplayCell for DateDescription { - fn display_content(&self, s: &str) -> String { - match s.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", s, e); - String::new() - } - } - } -} - -impl StringifyAnyData for DateDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for DateDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { match String::from_utf8(data.value) { Ok(s) => match s.parse::() { Ok(timestamp) => { @@ -142,14 +107,11 @@ impl StringifyAnyData for DateDescription { } } - fn str_to_any_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let timestamp = s .parse::() .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(AnyData::from_str( - &DateDescription::field_type(), - &format!("{}", timestamp), - )) + Ok(AnyData::from_str(self.field_type(), &format!("{}", timestamp))) } } @@ -237,54 +199,42 @@ impl std::default::Default for TimeFormat { // Single select #[derive(Clone, Debug, ProtoBuf, Default)] -pub struct SingleSelect { +pub struct SingleSelectDescription { #[pb(index = 1)] pub options: Vec, #[pb(index = 2)] pub disable_color: bool, } -impl_any_data!(SingleSelect, FieldType::SingleSelect); +impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); -impl StringifyAnyData for SingleSelect { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for SingleSelectDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(&SingleSelect::field_type(), s)) - } -} - -impl DisplayCell for SingleSelect { - fn display_content(&self, s: &str) -> String { - s.to_string() + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(AnyData::from_str(self.field_type(), s)) } } // Multiple select #[derive(Clone, Debug, ProtoBuf, Default)] -pub struct MultiSelect { +pub struct MultiSelectDescription { #[pb(index = 1)] pub options: Vec, #[pb(index = 2)] pub disable_color: bool, } -impl_any_data!(MultiSelect, FieldType::MultiSelect); -impl StringifyAnyData for MultiSelect { - fn stringify_any_data(&self, data: AnyData) -> String { +impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); +impl StringifyCellData for MultiSelectDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(&MultiSelect::field_type(), s)) - } -} - -impl DisplayCell for MultiSelect { - fn display_content(&self, s: &str) -> String { - s.to_string() + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(AnyData::from_str(self.field_type(), s)) } } @@ -314,7 +264,7 @@ impl SelectOption { #[derive(Clone, Debug, ProtoBuf)] pub struct NumberDescription { #[pb(index = 1)] - pub money: FlowyMoney, + pub money: MoneySymbol, #[pb(index = 2)] pub scale: u32, @@ -328,24 +278,26 @@ pub struct NumberDescription { #[pb(index = 5)] pub name: String, } -impl_any_data!(NumberDescription, FieldType::Number); +impl_from_and_to_type_option!(NumberDescription, FieldType::Number); impl std::default::Default for NumberDescription { fn default() -> Self { + let money = MoneySymbol::default(); + let symbol = money.symbol_str(); NumberDescription { - money: FlowyMoney::default(), + money, scale: 0, - symbol: String::new(), + symbol, sign_positive: true, - name: String::new(), + name: "Number".to_string(), } } } impl NumberDescription { - pub fn set_money(&mut self, money: FlowyMoney) { - self.money = money; - self.symbol = money.symbol(); + pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { + self.money = money_symbol; + self.symbol = money_symbol.symbol_str(); } fn money_from_str(&self, s: &str) -> Option { @@ -368,17 +320,8 @@ impl NumberDescription { } } -impl DisplayCell for NumberDescription { - fn display_content(&self, s: &str) -> String { - match self.money_from_str(s) { - Some(money_str) => money_str, - None => String::default(), - } - } -} - -impl StringifyAnyData for NumberDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for NumberDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { match String::from_utf8(data.value) { Ok(s) => match self.money_from_str(&s) { Some(money_str) => money_str, @@ -391,47 +334,47 @@ impl StringifyAnyData for NumberDescription { } } - fn str_to_any_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let strip_symbol_money = strip_money_symbol(s); let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; let money_str = decimal.to_string(); - Ok(AnyData::from_str(&NumberDescription::field_type(), &money_str)) + Ok(AnyData::from_str(self.field_type(), &money_str)) } } #[derive(Clone, Copy, Debug, EnumIter, ProtoBuf_Enum)] -pub enum FlowyMoney { +pub enum MoneySymbol { CNY = 0, EUR = 1, USD = 2, } -impl std::default::Default for FlowyMoney { +impl std::default::Default for MoneySymbol { fn default() -> Self { - FlowyMoney::USD + MoneySymbol::USD } } -impl FlowyMoney { +impl MoneySymbol { // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_symbol_str(s: &str) -> FlowyMoney { + pub fn from_symbol_str(s: &str) -> MoneySymbol { match s { - "CNY" => FlowyMoney::CNY, - "EUR" => FlowyMoney::EUR, - "USD" => FlowyMoney::USD, - _ => FlowyMoney::CNY, + "CNY" => MoneySymbol::CNY, + "EUR" => MoneySymbol::EUR, + "USD" => MoneySymbol::USD, + _ => MoneySymbol::CNY, } } - pub fn from_money(money: &rusty_money::Money) -> FlowyMoney { - FlowyMoney::from_symbol_str(&money.currency().symbol.to_string()) + pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { + MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) } pub fn currency(&self) -> &'static Currency { match self { - FlowyMoney::CNY => CNY, - FlowyMoney::EUR => EUR, - FlowyMoney::USD => USD, + MoneySymbol::CNY => CNY, + MoneySymbol::EUR => EUR, + MoneySymbol::USD => USD, } } @@ -442,7 +385,7 @@ impl FlowyMoney { self.currency().iso_alpha_code.to_string() } - pub fn symbol(&self) -> String { + pub fn symbol_str(&self) -> String { self.currency().symbol.to_string() } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index f9cf627d83..b6f55e6cfa 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -38,7 +38,7 @@ impl ClientGridEditor { ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); - let grid_pad = rev_manager.load::(cloud).await?; + let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); @@ -55,12 +55,12 @@ impl ClientGridEditor { })) } - pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { + pub async fn create_field(&self, field: Field) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; Ok(()) } - pub async fn delete_field(&mut self, field_id: &str) -> FlowyResult<()> { + pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; Ok(()) } @@ -125,6 +125,13 @@ impl ClientGridEditor { } } +#[cfg(feature = "flowy_unit_test")] +impl ClientGridEditor { + pub fn rev_manager(&self) -> Arc { + self.rev_manager.clone() + } +} + async fn load_all_fields( grid_pad: &GridMetaPad, kv_persistence: &Arc, @@ -143,7 +150,7 @@ async fn load_all_fields( Ok(map) } -struct GridPadBuilder(); +pub struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridMetaPad; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 6704d6a718..10160e115a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -27,7 +27,7 @@ impl ClientGridBlockMetaEditor { let cloud = Arc::new(GridBlockMetaRevisionCloudService { token: token.to_owned(), }); - let block_meta_pad = rev_manager.load::(cloud).await?; + let block_meta_pad = rev_manager.load::(Some(cloud)).await?; let meta_pad = Arc::new(RwLock::new(block_meta_pad)); let rev_manager = Arc::new(rev_manager); let user_id = user_id.to_owned(); diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 340a260b09..552f8cfe56 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,7 +1,6 @@ mod util; -pub mod cell_data; +pub mod field; pub mod grid_editor; pub mod grid_meta_editor; pub mod kv_persistence; -pub mod stringify; diff --git a/frontend/rust-lib/flowy-grid/src/services/stringify.rs b/frontend/rust-lib/flowy-grid/src/services/stringify.rs deleted file mode 100644 index a9154a5809..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/stringify.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::services::cell_data::*; -use crate::services::util::*; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; - -#[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { - match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_to_any_data(s), - FieldType::Number => NumberDescription::from(field).str_to_any_data(s), - FieldType::DateTime => DateDescription::from(field).str_to_any_data(s), - FieldType::SingleSelect => SingleSelect::from(field).str_to_any_data(s), - FieldType::MultiSelect => MultiSelect::from(field).str_to_any_data(s), - FieldType::Checkbox => CheckboxDescription::from(field).str_to_any_data(s), - } -} - -pub(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result { - let _ = check_type_id(&data, field)?; - let s = match field.field_type { - FieldType::RichText => RichTextDescription::from(field).stringify_any_data(data), - FieldType::Number => NumberDescription::from(field).stringify_any_data(data), - FieldType::DateTime => DateDescription::from(field).stringify_any_data(data), - FieldType::SingleSelect => SingleSelect::from(field).stringify_any_data(data), - FieldType::MultiSelect => MultiSelect::from(field).stringify_any_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).stringify_any_data(data), - }; - Ok(s) -} diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index 8fa196956d..a82e748a3e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,4 +1,4 @@ -use crate::services::cell_data::FlowyMoney; +use crate::services::field::MoneySymbol; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; use lazy_static::lazy_static; @@ -16,8 +16,8 @@ lazy_static! { fn generate_currency_by_symbol() -> HashMap { let mut map: HashMap = HashMap::new(); - for money in FlowyMoney::iter() { - map.insert(money.symbol(), money.currency()); + for money in MoneySymbol::iter() { + map.insert(money.symbol_str(), money.currency()); } map } @@ -25,7 +25,7 @@ fn generate_currency_by_symbol() -> HashMap { #[allow(dead_code)] pub fn string_to_money(money_str: &str) -> Option> { let mut process_money_str = String::from(money_str); - let default_currency = FlowyMoney::from_symbol_str("CNY").currency(); + let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); if process_money_str.is_empty() { return None; @@ -65,7 +65,7 @@ pub fn money_from_str(s: &str) -> Option { } } decimal.set_sign_positive(true); - Some(FlowyMoney::USD.with_decimal(decimal).to_string()) + Some(MoneySymbol::USD.with_decimal(decimal).to_string()) } Err(e) => { tracing::debug!("Format {} to money failed, {:?}", s, e); diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs new file mode 100644 index 0000000000..8cf876a052 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -0,0 +1,30 @@ +use crate::services::field::*; +use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; +use flowy_grid_data_model::entities::{Field, FieldType}; + +pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { + let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + .name("Name") + .visibility(true) + .field_type(FieldType::RichText) + .build(); + + let single_select = SingleSelectTypeOptionsBuilder::new() + .option(SelectOption::new("Done")) + .option(SelectOption::new("Progress")); + + let single_select_field = FieldBuilder::new(single_select) + .name("Name") + .visibility(true) + .field_type(FieldType::SingleSelect) + .build(); + + GridBuilder::new(grid_id) + .add_field(text_field) + .add_field(single_select_field) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() + .unwrap() +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs new file mode 100644 index 0000000000..797315bb10 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -0,0 +1,16 @@ +use crate::grid::script::EditorScript::*; +use crate::grid::script::*; + +#[tokio::test] +async fn grid_creat_field_test() { + let scripts = vec![ + CreateField { + field: create_text_field(), + }, + CreateField { + field: create_single_select_field(), + }, + AssertGridMetaPad, + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/mod.rs b/frontend/rust-lib/flowy-grid/tests/grid/mod.rs new file mode 100644 index 0000000000..04b16720e5 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/mod.rs @@ -0,0 +1,2 @@ +mod grid_test; +mod script; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs new file mode 100644 index 0000000000..4e31aef2c4 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -0,0 +1,75 @@ +use flowy_grid::services::field::*; +use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_test::event_builder::FolderEventBuilder; +use flowy_test::helper::ViewTest; +use flowy_test::FlowySDKTest; +use std::sync::Arc; + +pub enum EditorScript { + CreateField { field: Field }, + CreateRow, + AssertGridMetaPad, +} + +pub struct GridEditorTest { + pub sdk: FlowySDKTest, + pub grid_id: String, + pub editor: Arc, +} + +impl GridEditorTest { + pub async fn new() -> Self { + let sdk = FlowySDKTest::default(); + let _ = sdk.init_user().await; + let test = ViewTest::new_grid_view(&sdk).await; + let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); + let grid_id = test.view.id; + Self { sdk, grid_id, editor } + } + + pub async fn run_scripts(&mut self, scripts: Vec) { + for script in scripts { + self.run_script(script).await; + } + } + + pub async fn run_script(&mut self, script: EditorScript) { + let grid_manager = self.sdk.grid_manager.clone(); + let pool = self.sdk.user_session.db_pool().unwrap(); + let rev_manager = self.editor.rev_manager(); + let cache = rev_manager.revision_cache().await; + + match script { + EditorScript::CreateField { field } => { + self.editor.create_field(field).await.unwrap(); + } + EditorScript::CreateRow => {} + EditorScript::AssertGridMetaPad => { + let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); + let grid_pad = grid_rev_manager.load::(None).await.unwrap(); + println!("{}", grid_pad.delta_str()); + } + } + } +} + +pub fn create_text_field() -> Field { + FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + .name("Name") + .visibility(true) + .field_type(FieldType::RichText) + .build() +} + +pub fn create_single_select_field() -> Field { + let single_select = SingleSelectTypeOptionsBuilder::new() + .option(SelectOption::new("Done")) + .option(SelectOption::new("Progress")); + + FieldBuilder::new(single_select) + .name("Name") + .visibility(true) + .field_type(FieldType::SingleSelect) + .build() +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid_test.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/frontend/rust-lib/flowy-grid/tests/main.rs b/frontend/rust-lib/flowy-grid/tests/main.rs new file mode 100644 index 0000000000..ec055c3bb9 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/main.rs @@ -0,0 +1 @@ +mod grid; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index e0906cc7f1..0646dbcc5b 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,7 +1,6 @@ use bytes::Bytes; use flowy_block::TextBlockManager; use flowy_collaboration::client_document::default::initial_quill_delta_string; -use flowy_collaboration::client_grid::make_default_grid; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; @@ -13,6 +12,7 @@ use flowy_folder::{ manager::FolderManager, }; use flowy_grid::manager::GridManager; +use flowy_grid::util::make_default_grid; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index d0ed5240c8..7b34bb8115 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -67,14 +67,14 @@ impl RevisionManager { } } - pub async fn load(&mut self, cloud: Arc) -> FlowyResult + pub async fn load(&mut self, cloud: Option>) -> FlowyResult where B: RevisionObjectBuilder, { let (revisions, rev_id) = RevisionLoader { object_id: self.object_id.clone(), user_id: self.user_id.clone(), - cloud: Some(cloud), + cloud, rev_persistence: self.rev_persistence.clone(), } .load() diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 83277b22c6..9c03c09bb5 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -25,11 +25,12 @@ pub struct ViewTest { } impl ViewTest { - pub async fn new(sdk: &FlowySDKTest) -> Self { + #[allow(dead_code)] + pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType) -> Self { let workspace = create_workspace(sdk, "Workspace", "").await; open_workspace(sdk, &workspace.id).await; let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await; - let view = create_view(sdk, &app.id).await; + let view = create_view(sdk, &app.id, data_type).await; Self { sdk: sdk.clone(), workspace, @@ -37,6 +38,16 @@ impl ViewTest { view, } } + + #[allow(dead_code)] + pub async fn new_grid_view(sdk: &FlowySDKTest) -> Self { + Self::new(sdk, ViewDataType::Grid).await + } + + #[allow(dead_code)] + pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self { + Self::new(sdk, ViewDataType::TextBlock).await + } } async fn create_workspace(sdk: &FlowySDKTest, name: &str, desc: &str) -> Workspace { @@ -82,13 +93,13 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s app } -async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View { +async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType) -> View { let request = CreateViewPayload { belong_to_id: app_id.to_string(), name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), - data_type: ViewDataType::TextBlock, + data_type, ext_data: "".to_string(), plugin_type: 0, }; diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index dbc41e28ae..30cd8cd2e0 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -25,8 +25,7 @@ impl GridBuilder { } } - pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { - let field = Field::new(name, desc, field_type); + pub fn add_field(mut self, field: Field) -> Self { self.fields.push(field); self } @@ -74,27 +73,16 @@ fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { Ok(()) } -pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { - GridBuilder::new(grid_id) - .add_field("Name", "", FieldType::RichText) - .add_field("Tags", "", FieldType::SingleSelect) - .add_empty_row() - .add_empty_row() - .add_empty_row() - .build() - .unwrap() -} - #[cfg(test)] mod tests { use crate::client_grid::GridBuilder; - use flowy_grid_data_model::entities::{FieldType, GridBlockMeta, GridMeta}; + use flowy_grid_data_model::entities::{Field, FieldType, GridBlockMeta, GridMeta}; #[test] fn create_default_grid_test() { let info = GridBuilder::new("1") - .add_field("Name", "", FieldType::RichText) - .add_field("Tags", "", FieldType::SingleSelect) + .add_field(Field::new("Name", "", FieldType::RichText)) + .add_field(Field::new("Tags", "", FieldType::SingleSelect)) .add_empty_row() .add_empty_row() .add_empty_row() diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index b5cdc96e31..7c19cb40af 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -163,8 +163,19 @@ impl std::default::Default for FieldType { } } +impl AsRef for FieldType { + fn as_ref(&self) -> &FieldType { + &self + } +} + +impl Into for &FieldType { + fn into(self) -> FieldType { + self.clone() + } +} + impl FieldType { - #[allow(dead_code)] pub fn type_id(&self) -> String { let ty = self.clone(); format!("{}", ty as u8) @@ -193,13 +204,13 @@ pub struct AnyData { } impl AnyData { - pub fn from_str(field_type: &FieldType, s: &str) -> AnyData { + pub fn from_str>(field_type: F, s: &str) -> AnyData { Self::from_bytes(field_type, s.as_bytes().to_vec()) } - pub fn from_bytes>(field_type: &FieldType, bytes: T) -> AnyData { + pub fn from_bytes, F: Into>(field_type: F, bytes: T) -> AnyData { AnyData { - type_id: field_type.type_id(), + type_id: field_type.into().type_id(), value: bytes.as_ref().to_vec(), } } From baa70f2ee63f19e5818c2fee8c6813a30d2e5242 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 22:52:24 +0800 Subject: [PATCH 034/179] chore: add grid unit test --- .../flowy-grid-data-model/meta.pb.dart | 20 +-- .../flowy-grid-data-model/meta.pbjson.dart | 8 +- frontend/rust-lib/Cargo.lock | 2 + frontend/rust-lib/flowy-block/src/lib.rs | 2 +- .../rust-lib/flowy-block/src/web_socket.rs | 4 +- .../flowy-block/tests/document/script.rs | 4 +- frontend/rust-lib/flowy-grid/Cargo.toml | 2 + .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-grid/src/macros.rs | 16 +- .../src/services/field/field_builder.rs | 14 +- .../src/services/field/type_options.rs | 21 +-- .../flowy-grid/src/services/grid_editor.rs | 9 +- .../flowy-grid/tests/grid/grid_test.rs | 90 ++++++++++- .../rust-lib/flowy-grid/tests/grid/script.rs | 24 ++- .../src/client_grid/grid_pad.rs | 41 ++--- .../src/entities/meta.rs | 6 +- .../src/protobuf/model/meta.rs | 152 ++++++++---------- .../src/protobuf/proto/meta.proto | 4 +- 18 files changed, 252 insertions(+), 169 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 344bef10da..92532babbe 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -215,7 +215,7 @@ class Field extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') ..hasRequiredFields = false ; @@ -228,7 +228,7 @@ class Field extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - AnyData? typeOptions, + $core.String? typeOptions, }) { final _result = create(); if (id != null) { @@ -342,15 +342,13 @@ class Field extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - AnyData get typeOptions => $_getN(7); + $core.String get typeOptions => $_getSZ(7); @$pb.TagNumber(8) - set typeOptions(AnyData v) { setField(8, v); } + set typeOptions($core.String v) { $_setString(7, v); } @$pb.TagNumber(8) $core.bool hasTypeOptions() => $_has(7); @$pb.TagNumber(8) void clearTypeOptions() => clearField(8); - @$pb.TagNumber(8) - AnyData ensureTypeOptions() => $_ensure(7); } enum FieldChangeset_OneOfName { @@ -432,7 +430,7 @@ class FieldChangeset extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') ..hasRequiredFields = false ; @@ -445,7 +443,7 @@ class FieldChangeset extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - AnyData? typeOptions, + $core.String? typeOptions, }) { final _result = create(); if (fieldId != null) { @@ -580,15 +578,13 @@ class FieldChangeset extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - AnyData get typeOptions => $_getN(7); + $core.String get typeOptions => $_getSZ(7); @$pb.TagNumber(8) - set typeOptions(AnyData v) { setField(8, v); } + set typeOptions($core.String v) { $_setString(7, v); } @$pb.TagNumber(8) $core.bool hasTypeOptions() => $_has(7); @$pb.TagNumber(8) void clearTypeOptions() => clearField(8); - @$pb.TagNumber(8) - AnyData ensureTypeOptions() => $_ensure(7); } class RepeatedField extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 04e7384c15..82d830f6e1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -69,12 +69,12 @@ const Field$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '10': 'typeOptions'}, ], }; /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIhCgx0eXBlX29wdGlvbnMYCCABKAlSC3R5cGVPcHRpb25z'); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', @@ -86,7 +86,7 @@ const FieldChangeset$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '9': 6, '10': 'typeOptions'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '9': 6, '10': 'typeOptions'}, ], '8': const [ const {'1': 'one_of_name'}, @@ -100,7 +100,7 @@ const FieldChangeset$json = const { }; /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); +final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEiMKDHR5cGVfb3B0aW9ucxgIIAEoCUgGUgt0eXBlT3B0aW9uc0INCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIVChNvbmVfb2ZfdHlwZV9vcHRpb25z'); @$core.Deprecated('Use repeatedFieldDescriptor instead') const RepeatedField$json = const { '1': 'RepeatedField', diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 5ae075afa3..a4c40e1735 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1073,6 +1073,8 @@ dependencies = [ "rayon", "rust_decimal", "rusty-money", + "serde", + "serde_json", "strum", "strum_macros", "tokio", diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-block/src/lib.rs index b75ed7e147..b3c9de44dc 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-block/src/lib.rs @@ -12,7 +12,7 @@ pub mod errors { pub use flowy_error::{internal_error, ErrorCode, FlowyError}; } -pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; +pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; use crate::errors::FlowyError; use flowy_collaboration::entities::text_block_info::{ diff --git a/frontend/rust-lib/flowy-block/src/web_socket.rs b/frontend/rust-lib/flowy-block/src/web_socket.rs index c6033286af..7450e4a6ae 100644 --- a/frontend/rust-lib/flowy-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-block/src/web_socket.rs @@ -1,4 +1,4 @@ -use crate::{queue::EditorCommand, DOCUMENT_SYNC_INTERVAL_IN_MILLIS}; +use crate::{queue::EditorCommand, TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS}; use bytes::Bytes; use flowy_collaboration::{ entities::{ @@ -36,7 +36,7 @@ pub(crate) async fn make_block_ws_manager( RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller)); let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider)); - let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); + let ping_duration = Duration::from_millis(TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS); let ws_manager = Arc::new(RevisionWebSocketManager::new( "Block", &doc_id, diff --git a/frontend/rust-lib/flowy-block/tests/document/script.rs b/frontend/rust-lib/flowy-block/tests/document/script.rs index 87f52a3e46..af237de010 100644 --- a/frontend/rust-lib/flowy-block/tests/document/script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/script.rs @@ -1,5 +1,5 @@ use flowy_block::editor::ClientTextBlockEditor; -use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; +use flowy_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS; use flowy_sync::disk::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; use lib_ot::{core::Interval, rich_text::RichTextDelta}; @@ -80,6 +80,6 @@ impl TextBlockEditorTest { assert_eq!(expected_delta, delta); } } - sleep(Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS)).await; + sleep(Duration::from_millis(TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS)).await; } } diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 48c7e346a4..fda64c7f66 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -33,6 +33,8 @@ dashmap = "4.0" tokio = {version = "1", features = ["sync"]} rayon = "1.5" parking_lot = "0.11" +serde = { version = "1.0", features = ["derive"] } +serde_json = {version = "1.0"} [dev-dependencies] flowy-test = { path = "../flowy-test" } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index b621d30a69..02f9a89206 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -35,7 +35,7 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_field = editor.get_fields(payload.field_orders).await?; + let repeated_field = editor.get_fields(Some(payload.field_orders)).await?; data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 9f2fedddc7..ce638f96b8 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -11,7 +11,7 @@ macro_rules! impl_from_field_type_option { ($target: ident) => { impl std::convert::From<&Field> for $target { fn from(field: &Field) -> $target { - match $target::try_from(Bytes::from(field.type_options.value.clone())) { + match serde_json::from_str(&field.type_options) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); @@ -32,19 +32,13 @@ macro_rules! impl_to_field_type_option { } } - impl std::convert::From<$target> for AnyData { + impl std::convert::From<$target> for String { fn from(field_description: $target) -> Self { - let field_type = field_description.field_type(); - match field_description.try_into() { - Ok(bytes) => { - let bytes: Bytes = bytes; - AnyData::from_bytes(field_type, bytes) - } + match serde_json::to_string(&field_description) { + Ok(s) => s, Err(e) => { tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); - // it's impossible to fail when unwrapping the default field type data - let default_bytes: Bytes = $target::default().try_into().unwrap(); - AnyData::from_bytes(field_type, default_bytes) + serde_json::to_string(&$target::default()).unwrap() } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 3870fc1359..86dab02b67 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -59,7 +59,7 @@ impl FieldBuilder { pub trait TypeOptionsBuilder { fn field_type(&self) -> FieldType; - fn build(&self) -> AnyData; + fn build(&self) -> String; } // Text @@ -76,7 +76,7 @@ impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -115,7 +115,7 @@ impl TypeOptionsBuilder for NumberTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -142,7 +142,7 @@ impl TypeOptionsBuilder for DateTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -165,7 +165,7 @@ impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -189,7 +189,7 @@ impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -211,7 +211,7 @@ impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index 1a417abe20..2b82d94f3a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -13,10 +13,11 @@ use rusty_money::{ iso::{Currency, CNY, EUR, USD}, Money, }; +use serde::{Deserialize, Serialize}; use std::str::FromStr; use strum_macros::EnumIter; -#[derive(Debug, Clone, ProtoBuf, Default)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct RichTextDescription { #[pb(index = 1)] pub format: String, @@ -34,7 +35,7 @@ impl StringifyCellData for RichTextDescription { } // Checkbox -#[derive(Debug, Clone, ProtoBuf, Default)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] pub struct CheckboxDescription { #[pb(index = 1)] pub is_selected: bool, @@ -56,7 +57,7 @@ impl StringifyCellData for CheckboxDescription { } // Date -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct DateDescription { #[pb(index = 1)] pub date_format: DateFormat, @@ -115,7 +116,7 @@ impl StringifyCellData for DateDescription { } } -#[derive(Clone, Debug, Copy, ProtoBuf_Enum)] +#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] pub enum DateFormat { Local = 0, US = 1, @@ -158,7 +159,7 @@ impl DateFormat { } } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, ProtoBuf_Enum)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] pub enum TimeFormat { TwelveHour = 0, TwentyFourHour = 1, @@ -198,7 +199,7 @@ impl std::default::Default for TimeFormat { } // Single select -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SingleSelectDescription { #[pb(index = 1)] pub options: Vec, @@ -219,7 +220,7 @@ impl StringifyCellData for SingleSelectDescription { } // Multiple select -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct MultiSelectDescription { #[pb(index = 1)] pub options: Vec, @@ -238,7 +239,7 @@ impl StringifyCellData for MultiSelectDescription { } } -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SelectOption { #[pb(index = 1)] pub id: String, @@ -261,7 +262,7 @@ impl SelectOption { } // Number -#[derive(Clone, Debug, ProtoBuf)] +#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] pub struct NumberDescription { #[pb(index = 1)] pub money: MoneySymbol, @@ -342,7 +343,7 @@ impl StringifyCellData for NumberDescription { } } -#[derive(Clone, Copy, Debug, EnumIter, ProtoBuf_Enum)] +#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] pub enum MoneySymbol { CNY = 0, EUR = 1, diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index b6f55e6cfa..9b3ce9eecf 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -9,7 +9,7 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + Field, FieldChangeset, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -60,6 +60,11 @@ impl ClientGridEditor { Ok(()) } + pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?; + Ok(()) + } + pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; Ok(()) @@ -81,7 +86,7 @@ impl ClientGridEditor { todo!() } - pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { + pub async fn get_fields(&self, field_orders: Option) -> FlowyResult { let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; Ok(fields) } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 797315bb10..cbdb457577 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,14 +1,98 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; +use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; +use flowy_grid_data_model::entities::FieldChangeset; #[tokio::test] -async fn grid_creat_field_test() { +async fn default_grid_test() { + let scripts = vec![AssertFieldCount(2), AssertGridMetaPad]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_create_field() { + let text_field = create_text_field(); + let single_select_field = create_single_select_field(); + let scripts = vec![ + AssertFieldCount(2), + CreateField { + field: text_field.clone(), + }, + AssertFieldEqual { + field_index: 2, + field: text_field, + }, + AssertFieldCount(3), + CreateField { + field: single_select_field.clone(), + }, + AssertFieldEqual { + field_index: 3, + field: single_select_field, + }, + AssertFieldCount(4), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_field_with_empty_change() { + let single_select_field = create_single_select_field(); + let change = FieldChangeset { + field_id: single_select_field.id.clone(), + name: None, + desc: None, + field_type: None, + frozen: None, + visibility: None, + width: None, + type_options: None, + }; + let scripts = vec![ CreateField { - field: create_text_field(), + field: single_select_field.clone(), }, + UpdateField { change }, + AssertFieldEqual { + field_index: 2, + field: single_select_field, + }, + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_field() { + let single_select_field = create_single_select_field(); + let mut cloned_field = single_select_field.clone(); + + let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); + single_select_type_options.options.push(SelectOption::new("Unknown")); + + let change = FieldChangeset { + field_id: single_select_field.id.clone(), + name: None, + desc: None, + field_type: None, + frozen: Some(true), + visibility: None, + width: Some(1000), + type_options: Some(single_select_type_options.clone().into()), + }; + + cloned_field.frozen = true; + cloned_field.width = 1000; + cloned_field.type_options = single_select_type_options.into(); + + let scripts = vec![ CreateField { - field: create_single_select_field(), + field: single_select_field.clone(), + }, + UpdateField { change }, + AssertFieldEqual { + field_index: 2, + field: cloned_field, }, AssertGridMetaPad, ]; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 4e31aef2c4..523e1d4e12 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,15 +1,21 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType}; +use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::event_builder::FolderEventBuilder; use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; +use std::time::Duration; +use tokio::time::sleep; pub enum EditorScript { CreateField { field: Field }, - CreateRow, + UpdateField { change: FieldChangeset }, + AssertFieldCount(usize), + AssertFieldEqual { field_index: usize, field: Field }, AssertGridMetaPad, + CreateRow, } pub struct GridEditorTest { @@ -44,12 +50,24 @@ impl GridEditorTest { EditorScript::CreateField { field } => { self.editor.create_field(field).await.unwrap(); } - EditorScript::CreateRow => {} + EditorScript::UpdateField { change } => { + self.editor.update_field(change).await.unwrap(); + } + EditorScript::AssertFieldCount(count) => { + assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); + } + EditorScript::AssertFieldEqual { field_index, field } => { + let repeated_fields = self.editor.get_fields(None).await.unwrap(); + let compared_field = repeated_fields[field_index].clone(); + assert_eq!(compared_field, field); + } EditorScript::AssertGridMetaPad => { + sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); let grid_pad = grid_rev_manager.load::(None).await.unwrap(); println!("{}", grid_pad.delta_str()); } + EditorScript::CreateRow => {} } } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 5b99afd9c2..12d1b14c5b 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -51,25 +51,30 @@ impl GridMetaPad { }) } - pub fn get_fields(&self, field_orders: RepeatedFieldOrder) -> CollaborateResult { - let field_by_field_id = self - .grid_meta - .fields - .iter() - .map(|field| (&field.id, field)) - .collect::>(); + pub fn get_fields(&self, field_orders: Option) -> CollaborateResult { + match field_orders { + None => Ok(self.grid_meta.fields.clone().into()), + Some(field_orders) => { + let field_by_field_id = self + .grid_meta + .fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); - let fields = field_orders - .iter() - .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { - None => { - tracing::error!("Can't find the field with id: {}", field_order.field_id); - None - } - Some(field) => Some((*field).clone()), - }) - .collect::>(); - Ok(fields.into()) + let fields = field_orders + .iter() + .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { + None => { + tracing::error!("Can't find the field with id: {}", field_order.field_id); + None + } + Some(field) => Some((*field).clone()), + }) + .collect::>(); + Ok(fields.into()) + } + } } pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult> { diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 7c19cb40af..8ef8df08e4 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -54,7 +54,7 @@ pub struct GridBlockMeta { pub rows: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] pub struct Field { #[pb(index = 1)] pub id: String, @@ -78,7 +78,7 @@ pub struct Field { pub width: i32, #[pb(index = 8)] - pub type_options: AnyData, + pub type_options: String, } impl Field { @@ -120,7 +120,7 @@ pub struct FieldChangeset { pub width: Option, #[pb(index = 8, one_of)] - pub type_options: Option, + pub type_options: Option, } #[derive(Debug, Default, ProtoBuf)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4cb13bf25e..cd222c2868 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -727,7 +727,7 @@ pub struct Field { pub frozen: bool, pub visibility: bool, pub width: i32, - pub type_options: ::protobuf::SingularPtrField, + pub type_options: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -882,47 +882,35 @@ impl Field { self.width = v; } - // .AnyData type_options = 8; + // string type_options = 8; - pub fn get_type_options(&self) -> &AnyData { - self.type_options.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_type_options(&self) -> &str { + &self.type_options } pub fn clear_type_options(&mut self) { self.type_options.clear(); } - pub fn has_type_options(&self) -> bool { - self.type_options.is_some() - } - // Param is passed by value, moved - pub fn set_type_options(&mut self, v: AnyData) { - self.type_options = ::protobuf::SingularPtrField::some(v); + pub fn set_type_options(&mut self, v: ::std::string::String) { + self.type_options = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_type_options(&mut self) -> &mut AnyData { - if self.type_options.is_none() { - self.type_options.set_default(); - } - self.type_options.as_mut().unwrap() + pub fn mut_type_options(&mut self) -> &mut ::std::string::String { + &mut self.type_options } // Take field - pub fn take_type_options(&mut self) -> AnyData { - self.type_options.take().unwrap_or_else(|| AnyData::new()) + pub fn take_type_options(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_options, ::std::string::String::new()) } } impl ::protobuf::Message for Field { fn is_initialized(&self) -> bool { - for v in &self.type_options { - if !v.is_initialized() { - return false; - } - }; true } @@ -964,7 +952,7 @@ impl ::protobuf::Message for Field { self.width = tmp; }, 8 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_options)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -999,9 +987,8 @@ impl ::protobuf::Message for Field { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } - if let Some(ref v) = self.type_options.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + if !self.type_options.is_empty() { + my_size += ::protobuf::rt::string_size(8, &self.type_options); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1030,10 +1017,8 @@ impl ::protobuf::Message for Field { if self.width != 0 { os.write_int32(7, self.width)?; } - if let Some(ref v) = self.type_options.as_ref() { - os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; + if !self.type_options.is_empty() { + os.write_string(8, &self.type_options)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1108,7 +1093,7 @@ impl ::protobuf::Message for Field { |m: &Field| { &m.width }, |m: &mut Field| { &mut m.width }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "type_options", |m: &Field| { &m.type_options }, |m: &mut Field| { &mut m.type_options }, @@ -1208,7 +1193,7 @@ pub enum FieldChangeset_oneof_one_of_width { #[derive(Clone,PartialEq,Debug)] pub enum FieldChangeset_oneof_one_of_type_options { - type_options(AnyData), + type_options(::std::string::String), } impl FieldChangeset { @@ -1440,13 +1425,13 @@ impl FieldChangeset { self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) } - // .AnyData type_options = 8; + // string type_options = 8; - pub fn get_type_options(&self) -> &AnyData { + pub fn get_type_options(&self) -> &str { match self.one_of_type_options { ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v, - _ => ::default_instance(), + _ => "", } } pub fn clear_type_options(&mut self) { @@ -1461,15 +1446,15 @@ impl FieldChangeset { } // Param is passed by value, moved - pub fn set_type_options(&mut self, v: AnyData) { + pub fn set_type_options(&mut self, v: ::std::string::String) { self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) } // Mutable pointer to the field. - pub fn mut_type_options(&mut self) -> &mut AnyData { + pub fn mut_type_options(&mut self) -> &mut ::std::string::String { if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options { } else { - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(AnyData::new())); + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(::std::string::String::new())); } match self.one_of_type_options { ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v, @@ -1478,25 +1463,20 @@ impl FieldChangeset { } // Take field - pub fn take_type_options(&mut self) -> AnyData { + pub fn take_type_options(&mut self) -> ::std::string::String { if self.has_type_options() { match self.one_of_type_options.take() { ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v, _ => panic!(), } } else { - AnyData::new() + ::std::string::String::new() } } } impl ::protobuf::Message for FieldChangeset { fn is_initialized(&self) -> bool { - if let Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) = self.one_of_type_options { - if !v.is_initialized() { - return false; - } - } true } @@ -1547,7 +1527,7 @@ impl ::protobuf::Message for FieldChangeset { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_message()?)); + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_string()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -1609,8 +1589,7 @@ impl ::protobuf::Message for FieldChangeset { if let ::std::option::Option::Some(ref v) = self.one_of_type_options { match v { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + my_size += ::protobuf::rt::string_size(8, &v); }, }; } @@ -1668,9 +1647,7 @@ impl ::protobuf::Message for FieldChangeset { if let ::std::option::Option::Some(ref v) = self.one_of_type_options { match v { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; + os.write_string(8, v)?; }, }; } @@ -1747,7 +1724,7 @@ impl ::protobuf::Message for FieldChangeset { FieldChangeset::has_width, FieldChangeset::get_width, )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, AnyData>( + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "type_options", FieldChangeset::has_type_options, FieldChangeset::get_type_options, @@ -3183,46 +3160,45 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ - RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ + RowMetaR\x04rows\"\xdb\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ - \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"\x87\x03\n\x0eFieldChangeset\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\ - \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ - \x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfie\ - ldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\ - \n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\ - \x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\x08\x20\ - \x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0b\ - one_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11\ - one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"\ - -\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ - \x05items\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06ty\ - peId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Ro\ - wMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\ - \x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\ - \x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06h\ - eight\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\ - \x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellM\ - etaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row\ - _id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\ - \x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvis\ - ibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChanges\ - et.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\ - \x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\ - \x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\ - \x11one_of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ - \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\ - \x04\x20\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\ - \x01(\x05R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\ - \x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSele\ - ct\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\ - \x05b\x06proto3\ + idth\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ + \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\ + _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\ + \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\ + ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\ + \x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\ + \x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x07\x20\ + \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\ + \x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of\ + _field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0c\ + one_of_widthB\x15\n\x13one_of_type_options\"-\n\rRepeatedField\x12\x1c\n\ + \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\ + \x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\ + \x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\ + \x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ + kId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByF\ + ieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\ + \x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\ + \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ + \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\ + \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\ + \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\ + field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ + llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ + value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\ + \x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\ + \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\ + \x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyD\ + ataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFi\ + eldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\ + \x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMult\ + iSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 43c7e67d76..503284f7b5 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -22,7 +22,7 @@ message Field { bool frozen = 5; bool visibility = 6; int32 width = 7; - AnyData type_options = 8; + string type_options = 8; } message FieldChangeset { string field_id = 1; @@ -32,7 +32,7 @@ message FieldChangeset { oneof one_of_frozen { bool frozen = 5; }; oneof one_of_visibility { bool visibility = 6; }; oneof one_of_width { int32 width = 7; }; - oneof one_of_type_options { AnyData type_options = 8; }; + oneof one_of_type_options { string type_options = 8; }; } message RepeatedField { repeated Field items = 1; From 572e38ec1c979cf6eb35db3acd9b982dd36fb780 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 13 Mar 2022 11:06:28 +0800 Subject: [PATCH 035/179] chore: config grid row changeset --- .../flowy-grid-data-model/grid.pb.dart | 48 ++--- .../flowy-grid-data-model/grid.pbjson.dart | 10 +- .../flowy-grid-data-model/meta.pb.dart | 66 +----- .../flowy-grid-data-model/meta.pbjson.dart | 9 +- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- .../flowy-grid/src/services/field/mod.rs | 2 - .../src/services/field/type_options.rs | 2 +- .../flowy-grid/src/services/grid_editor.rs | 139 ++++--------- .../src/services/grid_meta_editor.rs | 114 ++++++++++- .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../services/{field => row}/cell_stringify.rs | 0 .../flowy-grid/src/services/row/mod.rs | 7 + .../src/services/row/row_builder.rs | 24 +++ .../flowy-grid/src/services/row/row_loader.rs | 68 +++++++ .../flowy-grid/tests/grid/grid_test.rs | 76 ++++++- .../rust-lib/flowy-grid/tests/grid/script.rs | 35 +++- .../src/client_grid/block_pad.rs | 4 + .../src/client_grid/grid_builder.rs | 2 +- .../src/client_grid/grid_pad.rs | 27 ++- .../src/entities/grid.rs | 13 +- .../src/entities/meta.rs | 47 +++-- .../src/protobuf/model/grid.rs | 120 +++++------ .../src/protobuf/model/meta.rs | 188 +++--------------- .../src/protobuf/proto/grid.proto | 6 +- .../src/protobuf/proto/meta.proto | 7 +- 25 files changed, 555 insertions(+), 464 deletions(-) rename frontend/rust-lib/flowy-grid/src/services/{field => row}/cell_stringify.rs (100%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index c853bb867b..4122de9503 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -163,17 +163,22 @@ class RepeatedFieldOrder extends $pb.GeneratedMessage { class RowOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..hasRequiredFields = false ; RowOrder._() : super(); factory RowOrder({ $core.String? rowId, + $core.String? blockId, }) { final _result = create(); if (rowId != null) { _result.rowId = rowId; } + if (blockId != null) { + _result.blockId = blockId; + } return _result; } factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -205,6 +210,15 @@ class RowOrder extends $pb.GeneratedMessage { $core.bool hasRowId() => $_has(0); @$pb.TagNumber(1) void clearRowId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get blockId => $_getSZ(1); + @$pb.TagNumber(2) + set blockId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasBlockId() => $_has(1); + @$pb.TagNumber(2) + void clearBlockId() => clearField(2); } class RepeatedRowOrder extends $pb.GeneratedMessage { @@ -360,22 +374,17 @@ class RepeatedRow extends $pb.GeneratedMessage { class Cell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Cell', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') ..hasRequiredFields = false ; Cell._() : super(); factory Cell({ - $core.String? id, $core.String? fieldId, $core.String? content, }) { final _result = create(); - if (id != null) { - _result.id = id; - } if (fieldId != null) { _result.fieldId = fieldId; } @@ -406,31 +415,22 @@ class Cell extends $pb.GeneratedMessage { static Cell? _defaultInstance; @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); + $core.String get fieldId => $_getSZ(0); @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } + set fieldId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); + $core.bool hasFieldId() => $_has(0); @$pb.TagNumber(1) - void clearId() => clearField(1); + void clearFieldId() => clearField(1); @$pb.TagNumber(2) - $core.String get fieldId => $_getSZ(1); + $core.String get content => $_getSZ(1); @$pb.TagNumber(2) - set fieldId($core.String v) { $_setString(1, v); } + set content($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasFieldId() => $_has(1); + $core.bool hasContent() => $_has(1); @$pb.TagNumber(2) - void clearFieldId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get content => $_getSZ(2); - @$pb.TagNumber(3) - set content($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasContent() => $_has(2); - @$pb.TagNumber(3) - void clearContent() => clearField(3); + void clearContent() => clearField(2); } class CreateGridPayload extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 96bfd55dfd..2c1a16296d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -45,11 +45,12 @@ const RowOrder$json = const { '1': 'RowOrder', '2': const [ const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, ], }; /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lk'); +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lk'); @$core.Deprecated('Use repeatedRowOrderDescriptor instead') const RepeatedRowOrder$json = const { '1': 'RepeatedRowOrder', @@ -97,14 +98,13 @@ final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZ const Cell$json = const { '1': 'Cell', '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'content', '3': 3, '4': 1, '5': 9, '10': 'content'}, + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'content', '3': 2, '4': 1, '5': 9, '10': 'content'}, ], }; /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAMgASgJUgdjb250ZW50'); +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 92532babbe..25104afa46 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -897,38 +897,23 @@ class RowMetaChangeset extends $pb.GeneratedMessage { class CellMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) - ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; CellMeta._() : super(); factory CellMeta({ - $core.String? id, - $core.String? rowId, $core.String? fieldId, - AnyData? data, - $core.int? height, + $core.String? data, }) { final _result = create(); - if (id != null) { - _result.id = id; - } - if (rowId != null) { - _result.rowId = rowId; - } if (fieldId != null) { _result.fieldId = fieldId; } if (data != null) { _result.data = data; } - if (height != null) { - _result.height = height; - } return _result; } factory CellMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -953,50 +938,21 @@ class CellMeta extends $pb.GeneratedMessage { static CellMeta? _defaultInstance; @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); + $core.String get fieldId => $_getSZ(0); @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } + set fieldId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); + $core.bool hasFieldId() => $_has(0); @$pb.TagNumber(1) - void clearId() => clearField(1); + void clearFieldId() => clearField(1); @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); + $core.String get data => $_getSZ(1); @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } + set data($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); + $core.bool hasData() => $_has(1); @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get fieldId => $_getSZ(2); - @$pb.TagNumber(3) - set fieldId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFieldId() => $_has(2); - @$pb.TagNumber(3) - void clearFieldId() => clearField(3); - - @$pb.TagNumber(4) - AnyData get data => $_getN(3); - @$pb.TagNumber(4) - set data(AnyData v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); - @$pb.TagNumber(4) - AnyData ensureData() => $_ensure(3); - - @$pb.TagNumber(5) - $core.int get height => $_getIZ(4); - @$pb.TagNumber(5) - set height($core.int v) { $_setSignedInt32(4, v); } - @$pb.TagNumber(5) - $core.bool hasHeight() => $_has(4); - @$pb.TagNumber(5) - void clearHeight() => clearField(5); + void clearData() => clearField(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 82d830f6e1..322b477e30 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -179,13 +179,10 @@ final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode(' const CellMeta$json = const { '1': 'CellMeta', '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, - const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 2, '4': 1, '5': 9, '10': 'data'}, ], }; /// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIcCgRkYXRhGAQgASgLMgguQW55RGF0YVIEZGF0YRIWCgZoZWlnaHQYBSABKAVSBmhlaWdodA=='); +final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBISCgRkYXRhGAIgASgJUgRkYXRh'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 02f9a89206..0861f2aaa1 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row = editor.get_rows(payload.row_orders).await?; + let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); data_result(repeated_row) } @@ -35,7 +35,7 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_field = editor.get_fields(Some(payload.field_orders)).await?; + let repeated_field: RepeatedField = editor.get_fields(Some(payload.field_orders)).await?.into(); data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 157e5145c2..61b5889e68 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,7 +1,5 @@ -mod cell_stringify; mod field_builder; mod type_options; -pub use cell_stringify::*; pub use field_builder::*; pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index 2b82d94f3a..b192a1e118 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -1,6 +1,6 @@ #![allow(clippy::upper_case_acronyms)] use crate::impl_from_and_to_type_option; -use crate::services::field::StringifyCellData; +use crate::services::row::StringifyCellData; use crate::services::util::*; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 9b3ce9eecf..4b7250079e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::grid_meta_editor::ClientGridBlockMetaEditor; +use crate::services::grid_meta_editor::{ClientGridBlockMetaEditor, GridBlockMetaEditorManager}; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; @@ -9,7 +9,8 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedField, RepeatedFieldOrder, RepeatedRow, + RepeatedRowOrder, Row, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -43,7 +44,7 @@ impl ClientGridEditor { let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); let block_meta_manager = - Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks()).await?); + Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks().clone()).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -70,27 +71,60 @@ impl ClientGridEditor { Ok(()) } + pub async fn create_block(&self, grid_block: GridBlock) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; + Ok(()) + } + + pub async fn update_block(&self, change: GridBlockChangeset) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.update_block(change)?)).await?; + Ok(()) + } + pub async fn create_row(&self) -> FlowyResult<()> { - todo!() + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + match self.grid_meta_pad.read().await.get_blocks().last() { + None => Err(FlowyError::internal().context("There is no grid block in this grid")), + Some(grid_block) => { + let row_count = self.block_meta_manager.create_row(fields, grid_block).await?; + let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); + let _ = self.update_block(change).await?; + Ok(()) + } + } } - pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { - todo!() + pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; + Ok(rows) } - pub async fn delete_rows(&self, _ids: Vec) -> FlowyResult<()> { - todo!() + pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { + let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; + for (block_id, row_count) in row_counts { + let _ = self + .update_block(GridBlockChangeset::from_row_count(&block_id, row_count)) + .await?; + } + + Ok(()) } pub async fn grid_data(&self) -> Grid { todo!() } - pub async fn get_fields(&self, field_orders: Option) -> FlowyResult { + pub async fn get_fields(&self, field_orders: Option) -> FlowyResult> { let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; Ok(fields) } + pub async fn get_blocks(&self) -> FlowyResult> { + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + Ok(grid_blocks) + } + pub async fn delta_str(&self) -> String { self.grid_meta_pad.read().await.delta_str() } @@ -184,90 +218,3 @@ impl RevisionCompactor for GridRevisionCompactor { Ok(delta.to_bytes()) } } - -struct GridBlockMetaEditorManager { - editor_map: DashMap>, -} - -impl GridBlockMetaEditorManager { - async fn new(user: &Arc, blocks: Vec) -> FlowyResult { - let editor_map = make_block_meta_editor_map(user, blocks).await?; - let manager = Self { editor_map }; - Ok(manager) - } - - async fn get_editor(&self, _block_id: &str) -> Arc { - todo!() - } - - pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { - // let ids = row_orders - // .items - // .into_iter() - // .map(|row_order| row_order.row_id) - // .collect::>(); - // let row_metas: Vec = self.kv_persistence.batch_get(ids)?; - // - // let make_cell = |field_id: String, raw_cell: CellMeta| { - // let some_field = self.field_map.get(&field_id); - // if some_field.is_none() { - // tracing::error!("Can't find the field with {}", field_id); - // return None; - // } - // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - // - // let field = some_field.unwrap(); - // match stringify_deserialize(raw_cell.data, field.value()) { - // Ok(content) => { - // let cell = Cell { - // id: raw_cell.id, - // field_id: field_id.clone(), - // content, - // }; - // Some((field_id, cell)) - // } - // Err(_) => None, - // } - // }; - // - // let rows = row_metas - // .into_par_iter() - // .map(|row_meta| { - // let mut row = Row { - // id: row_meta.id.clone(), - // cell_by_field_id: Default::default(), - // height: row_meta.height, - // }; - // row.cell_by_field_id = row_meta - // .cell_by_field_id - // .into_par_iter() - // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - // .collect::>(); - // row - // }) - // .collect::>(); - // - // Ok(rows.into()) - todo!() - } -} - -async fn make_block_meta_editor_map( - user: &Arc, - blocks: Vec, -) -> FlowyResult>> { - let token = user.token()?; - let user_id = user.user_id()?; - let pool = user.db_pool()?; - - let editor_map = DashMap::new(); - for block in blocks { - let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool.clone())); - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, &block.id, disk_cache)); - let rev_manager = RevisionManager::new(&user_id, &block.id, rev_persistence); - let editor = ClientGridBlockMetaEditor::new(&user_id, &token, &block.id, rev_manager).await?; - editor_map.insert(block.id, Arc::new(editor)); - } - - Ok(editor_map) -} diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 10160e115a..5358b4cde5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,15 +1,110 @@ +use crate::manager::GridUser; +use crate::services::row::{make_row_ids_per_block, make_rows, sort_rows, RowBuilder}; use bytes::Bytes; +use dashmap::mapref::one::Ref; +use dashmap::DashMap; use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; -use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; +use flowy_grid_data_model::entities::{ + Field, GridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, +}; +use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; +use flowy_sync::{ + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, +}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; +use lib_sqlite::ConnectionPool; +use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; +pub(crate) struct GridBlockMetaEditorManager { + user: Arc, + editor_map: DashMap>, +} + +impl GridBlockMetaEditorManager { + pub(crate) async fn new(user: &Arc, blocks: Vec) -> FlowyResult { + let editor_map = make_block_meta_editor_map(user, blocks).await?; + let user = user.clone(); + let manager = Self { user, editor_map }; + Ok(manager) + } + + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + match self.editor_map.get(block_id) { + None => { + tracing::error!("The is a fatal error, block is not exist"); + let editor = Arc::new(make_block_meta_editor(&self.user, block_id).await?); + self.editor_map.insert(block_id.to_owned(), editor.clone()); + Ok(editor) + } + Some(editor) => Ok(editor.clone()), + } + } + + pub(crate) async fn create_row(&self, fields: Vec, grid_block: &GridBlock) -> FlowyResult { + let row = RowBuilder::new(&fields, &grid_block.id).build(); + let editor = self.get_editor(&grid_block.id).await?; + editor.create_row(row).await + } + + pub(crate) async fn delete_rows(&self, row_orders: Option) -> FlowyResult> { + Ok(vec![("".to_owned(), 2)]) + } + + pub(crate) async fn get_rows( + &self, + fields: Vec, + row_orders: Option, + ) -> FlowyResult> { + match row_orders { + None => { + let rows = vec![]; + Ok(rows) + } + Some(row_orders) => { + let row_ids_per_blocks = make_row_ids_per_block(&row_orders); + let mut rows = vec![]; + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let row_metas = editor.get_rows(row_ids_per_block.row_ids).await?; + rows.extend(make_rows(&fields, row_metas)); + } + sort_rows(&mut rows, row_orders); + Ok(rows) + } + } + } +} + +async fn make_block_meta_editor_map( + user: &Arc, + blocks: Vec, +) -> FlowyResult>> { + let editor_map = DashMap::new(); + for block in blocks { + let editor = make_block_meta_editor(user, &block.id).await?; + editor_map.insert(block.id, Arc::new(editor)); + } + + Ok(editor_map) +} + +async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { + let token = user.token()?; + let user_id = user.user_id()?; + let pool = user.db_pool()?; + + let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache)); + let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence); + ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await +} + pub struct ClientGridBlockMetaEditor { user_id: String, pub block_id: String, @@ -40,10 +135,17 @@ impl ClientGridBlockMetaEditor { }) } - async fn create_row(&self) -> FlowyResult<()> { - let row = RowMeta::new(&self.block_id, vec![]); - let _ = self.modify(|pad| Ok(pad.add_row(row)?)).await?; - Ok(()) + async fn create_row(&self, row: RowMeta) -> FlowyResult { + let mut row_count = 0; + let _ = self + .modify(|pad| { + let change = pad.add_row(row)?; + row_count = pad.number_of_rows(); + Ok(change) + }) + .await?; + + Ok(row_count) } pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 552f8cfe56..0a7918b5d6 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -4,3 +4,4 @@ pub mod field; pub mod grid_editor; pub mod grid_meta_editor; pub mod kv_persistence; +pub mod row; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs rename to frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs new file mode 100644 index 0000000000..baac627e00 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -0,0 +1,7 @@ +mod cell_stringify; +mod row_builder; +mod row_loader; + +pub use cell_stringify::*; +pub use row_builder::*; +pub use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs new file mode 100644 index 0000000000..d88b580788 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -0,0 +1,24 @@ +use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta}; + +pub struct RowBuilder<'a> { + fields: &'a Vec, + row: RowMeta, +} + +impl<'a> RowBuilder<'a> { + pub fn new(fields: &'a Vec, block_id: &'a String) -> Self { + let row = RowMeta::new(block_id); + Self { fields, row } + } + + #[allow(dead_code)] + pub fn add_cell(mut self, field_id: &str, data: String) -> Self { + let cell = CellMeta::new(field_id, data); + self.row.cell_by_field_id.insert(field_id.to_owned(), cell); + self + } + + pub fn build(self) -> RowMeta { + self.row + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs new file mode 100644 index 0000000000..f9092a5d89 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -0,0 +1,68 @@ +use flowy_grid_data_model::entities::{Field, RepeatedRowOrder, Row, RowMeta}; +use std::collections::HashMap; + +pub(crate) struct RowIdsPerBlock { + pub(crate) block_id: String, + pub(crate) row_ids: Vec, +} + +pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec { + let mut map: HashMap = HashMap::new(); + row_orders.iter().for_each(|row_order| { + let block_id = row_order.block_id.clone(); + let entry = map.entry(block_id.clone()).or_insert(RowIdsPerBlock { + block_id, + row_ids: vec![], + }); + entry.row_ids.push(row_order.row_id.clone()); + }); + map.into_values().collect::>() +} + +pub(crate) fn sort_rows(rows: &mut Vec, row_orders: RepeatedRowOrder) { + todo!() +} + +pub(crate) fn make_rows(fields: &Vec, rows: Vec) -> Vec { + // let make_cell = |field_id: String, raw_cell: CellMeta| { + // let some_field = self.field_map.get(&field_id); + // if some_field.is_none() { + // tracing::error!("Can't find the field with {}", field_id); + // return None; + // } + // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); + // + // let field = some_field.unwrap(); + // match stringify_deserialize(raw_cell.data, field.value()) { + // Ok(content) => { + // let cell = Cell { + // id: raw_cell.id, + // field_id: field_id.clone(), + // content, + // }; + // Some((field_id, cell)) + // } + // Err(_) => None, + // } + // }; + // + // let rows = row_metas + // .into_par_iter() + // .map(|row_meta| { + // let mut row = Row { + // id: row_meta.id.clone(), + // cell_by_field_id: Default::default(), + // height: row_meta.height, + // }; + // row.cell_by_field_id = row_meta + // .cell_by_field_id + // .into_par_iter() + // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) + // .collect::>(); + // row + // }) + // .collect::>(); + // + // Ok(rows.into()) + todo!() +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index cbdb457577..42af2ef4c4 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; -use flowy_grid_data_model::entities::FieldChangeset; +use flowy_grid_data_model::entities::{FieldChangeset, GridBlock, GridBlockChangeset}; #[tokio::test] async fn default_grid_test() { @@ -35,6 +35,23 @@ async fn grid_create_field() { GridEditorTest::new().await.run_scripts(scripts).await; } +#[tokio::test] +async fn grid_create_duplicate_field() { + let text_field = create_text_field(); + let scripts = vec![ + AssertFieldCount(2), + CreateField { + field: text_field.clone(), + }, + AssertFieldCount(3), + CreateField { + field: text_field.clone(), + }, + AssertFieldCount(3), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + #[tokio::test] async fn grid_update_field_with_empty_change() { let single_select_field = create_single_select_field(); @@ -98,3 +115,60 @@ async fn grid_update_field() { ]; GridEditorTest::new().await.run_scripts(scripts).await; } + +#[tokio::test] +async fn grid_delete_field() { + let text_field = create_text_field(); + let scripts = vec![ + CreateField { + field: text_field.clone(), + }, + AssertFieldCount(3), + DeleteField { field: text_field }, + AssertFieldCount(2), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_create_block() { + let grid_block = GridBlock::new(); + let scripts = vec![ + AssertBlockCount(1), + CreateBlock { block: grid_block }, + AssertBlockCount(2), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_block() { + let grid_block = GridBlock::new(); + let mut cloned_grid_block = grid_block.clone(); + let change = GridBlockChangeset { + block_id: grid_block.id.clone(), + start_row_index: Some(2), + row_count: Some(10), + }; + + cloned_grid_block.start_row_index = 2; + cloned_grid_block.row_count = 10; + + let scripts = vec![ + AssertBlockCount(1), + CreateBlock { block: grid_block }, + UpdateBlock { change }, + AssertBlockCount(2), + AssertBlockEqual { + block_index: 1, + block: cloned_grid_block, + }, + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_create_row() { + let scripts = vec![AssertRowCount(2), CreateRow, CreateRow, CreateRow, AssertRowCount(5)]; + GridEditorTest::new().await.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 523e1d4e12..277cd6b4da 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,6 +1,6 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::event_builder::FolderEventBuilder; use flowy_test::helper::ViewTest; @@ -12,10 +12,17 @@ use tokio::time::sleep; pub enum EditorScript { CreateField { field: Field }, UpdateField { change: FieldChangeset }, + DeleteField { field: Field }, AssertFieldCount(usize), AssertFieldEqual { field_index: usize, field: Field }, - AssertGridMetaPad, + CreateBlock { block: GridBlock }, + UpdateBlock { change: GridBlockChangeset }, + AssertBlockCount(usize), + AssertBlockEqual { block_index: usize, block: GridBlock }, CreateRow, + AssertRowCount(usize), + // AssertRowEqual{ row_index: usize, row: RowMeta}, + AssertGridMetaPad, } pub struct GridEditorTest { @@ -53,6 +60,9 @@ impl GridEditorTest { EditorScript::UpdateField { change } => { self.editor.update_field(change).await.unwrap(); } + EditorScript::DeleteField { field } => { + self.editor.delete_field(&field.id).await.unwrap(); + } EditorScript::AssertFieldCount(count) => { assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); } @@ -61,13 +71,32 @@ impl GridEditorTest { let compared_field = repeated_fields[field_index].clone(); assert_eq!(compared_field, field); } + EditorScript::CreateBlock { block } => { + self.editor.create_block(block).await.unwrap(); + } + EditorScript::UpdateBlock { change } => { + self.editor.update_block(change).await.unwrap(); + } + EditorScript::AssertBlockCount(count) => { + assert_eq!(self.editor.get_blocks().await.unwrap().len(), count); + } + EditorScript::AssertBlockEqual { block_index, block } => { + let blocks = self.editor.get_blocks().await.unwrap(); + let compared_block = blocks[block_index].clone(); + assert_eq!(compared_block, block); + } + EditorScript::CreateRow => { + self.editor.create_row().await.unwrap(); + } + EditorScript::AssertRowCount(count) => { + assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); let grid_pad = grid_rev_manager.load::(None).await.unwrap(); println!("{}", grid_pad.delta_str()); } - EditorScript::CreateRow => {} } } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 1252f0d842..b63c667cbd 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -69,6 +69,10 @@ impl GridBlockMetaPad { .collect::>()) } + pub fn number_of_rows(&self) -> i32 { + self.rows.len() as i32 + } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 30cd8cd2e0..9ba6cc7ff5 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -31,7 +31,7 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.grid_block.id, vec![]); + let row = RowMeta::new(&self.grid_block.id); self.grid_block_meta.rows.push(row); self } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 12d1b14c5b..304919a310 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -36,8 +36,13 @@ impl GridMetaPad { pub fn create_field(&mut self, field: Field) -> CollaborateResult> { self.modify_grid(|grid| { - grid.fields.push(field); - Ok(Some(())) + if grid.fields.contains(&field) { + tracing::warn!("Duplicate grid field"); + Ok(None) + } else { + grid.fields.push(field); + Ok(Some(())) + } }) } @@ -51,7 +56,7 @@ impl GridMetaPad { }) } - pub fn get_fields(&self, field_orders: Option) -> CollaborateResult { + pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { match field_orders { None => Ok(self.grid_meta.fields.clone().into()), Some(field_orders) => { @@ -72,7 +77,7 @@ impl GridMetaPad { Some(field) => Some((*field).clone()), }) .collect::>(); - Ok(fields.into()) + Ok(fields) } } } @@ -122,8 +127,13 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { - grid.blocks.push(block); - Ok(Some(())) + if grid.blocks.iter().find(|b| b.id == block.id).is_some() { + tracing::warn!("Duplicate grid block"); + Ok(None) + } else { + grid.blocks.push(block); + Ok(Some(())) + } }) } @@ -141,6 +151,11 @@ impl GridMetaPad { is_changed = Some(()); } + if let Some(start_row_index) = change.start_row_index { + block.start_row_index = start_row_index; + is_changed = Some(()); + } + Ok(is_changed) }) } diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 00c3981d79..d2bf2173f3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -45,11 +45,17 @@ impl std::ops::Deref for RepeatedFieldOrder { pub struct RowOrder { #[pb(index = 1)] pub row_id: String, + + #[pb(index = 2)] + pub block_id: String, } impl std::convert::From<&RowMeta> for RowOrder { fn from(row: &RowMeta) -> Self { - Self { row_id: row.id.clone() } + Self { + row_id: row.id.clone(), + block_id: row.block_id.clone(), + } } } @@ -111,12 +117,9 @@ impl std::convert::From> for RepeatedRow { #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] pub field_id: String, - #[pb(index = 3)] + #[pb(index = 2)] pub content: String, } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 8ef8df08e4..2813759448 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -18,7 +18,7 @@ pub struct GridMeta { pub blocks: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] pub id: String, @@ -45,6 +45,16 @@ pub struct GridBlockChangeset { pub row_count: Option, } +impl GridBlockChangeset { + pub fn from_row_count(block_id: &str, row_count: i32) -> Self { + Self { + block_id: block_id.to_string(), + start_row_index: None, + row_count: Some(row_count), + } + } +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct GridBlockMeta { #[pb(index = 1)] @@ -225,7 +235,7 @@ impl ToString for AnyData { } } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct RowMeta { #[pb(index = 1)] pub id: String, @@ -244,16 +254,11 @@ pub struct RowMeta { } impl RowMeta { - pub fn new(block_id: &str, cells: Vec) -> Self { - let cell_by_field_id = cells - .into_iter() - .map(|cell| (cell.id.clone(), cell)) - .collect::>(); - + pub fn new(block_id: &str) -> Self { Self { id: uuid::Uuid::new_v4().to_string(), block_id: block_id.to_owned(), - cell_by_field_id, + cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, } @@ -275,20 +280,20 @@ pub struct RowMetaChangeset { pub cell_by_field_id: HashMap, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct CellMeta { #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] pub field_id: String, - #[pb(index = 4)] - pub data: AnyData, - - #[pb(index = 5)] - pub height: i32, + #[pb(index = 2)] + pub data: String, +} + +impl CellMeta { + pub fn new(field_id: &str, data: String) -> Self { + Self { + field_id: field_id.to_string(), + data, + } + } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index c4f57568e9..e7a7561068 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -609,6 +609,7 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedFieldOrder { pub struct RowOrder { // message fields pub row_id: ::std::string::String, + pub block_id: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -650,6 +651,32 @@ impl RowOrder { pub fn take_row_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } + + // string block_id = 2; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } } impl ::protobuf::Message for RowOrder { @@ -664,6 +691,9 @@ impl ::protobuf::Message for RowOrder { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -679,6 +709,9 @@ impl ::protobuf::Message for RowOrder { if !self.row_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.row_id); } + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.block_id); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -688,6 +721,9 @@ impl ::protobuf::Message for RowOrder { if !self.row_id.is_empty() { os.write_string(1, &self.row_id)?; } + if !self.block_id.is_empty() { + os.write_string(2, &self.block_id)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -731,6 +767,11 @@ impl ::protobuf::Message for RowOrder { |m: &RowOrder| { &m.row_id }, |m: &mut RowOrder| { &mut m.row_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &RowOrder| { &m.block_id }, + |m: &mut RowOrder| { &mut m.block_id }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RowOrder", fields, @@ -748,6 +789,7 @@ impl ::protobuf::Message for RowOrder { impl ::protobuf::Clear for RowOrder { fn clear(&mut self) { self.row_id.clear(); + self.block_id.clear(); self.unknown_fields.clear(); } } @@ -1330,7 +1372,6 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRow { #[derive(PartialEq,Clone,Default)] pub struct Cell { // message fields - pub id: ::std::string::String, pub field_id: ::std::string::String, pub content: ::std::string::String, // special fields @@ -1349,33 +1390,7 @@ impl Cell { ::std::default::Default::default() } - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string field_id = 2; + // string field_id = 1; pub fn get_field_id(&self) -> &str { @@ -1401,7 +1416,7 @@ impl Cell { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string content = 3; + // string content = 2; pub fn get_content(&self) -> &str { @@ -1438,12 +1453,9 @@ impl ::protobuf::Message for Cell { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, - 3 => { + 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.content)?; }, _ => { @@ -1458,14 +1470,11 @@ impl ::protobuf::Message for Cell { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.field_id); + my_size += ::protobuf::rt::string_size(1, &self.field_id); } if !self.content.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.content); + my_size += ::protobuf::rt::string_size(2, &self.content); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1473,14 +1482,11 @@ impl ::protobuf::Message for Cell { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } if !self.field_id.is_empty() { - os.write_string(2, &self.field_id)?; + os.write_string(1, &self.field_id)?; } if !self.content.is_empty() { - os.write_string(3, &self.content)?; + os.write_string(2, &self.content)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1520,11 +1526,6 @@ impl ::protobuf::Message for Cell { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &Cell| { &m.id }, - |m: &mut Cell| { &mut m.id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "field_id", |m: &Cell| { &m.field_id }, @@ -1551,7 +1552,6 @@ impl ::protobuf::Message for Cell { impl ::protobuf::Clear for Cell { fn clear(&mut self) { - self.id.clear(); self.field_id.clear(); self.content.clear(); self.unknown_fields.clear(); @@ -2326,17 +2326,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\trowOrders\"'\ \n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"7\n\ \x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOr\ - derR\x05items\"!\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\ - \x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ - Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ - lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ - \x03(\x0b2\x04.RowR\x05items\"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\ - \x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ + derR\x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10R\ + epeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05\ + items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\ + \n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\ + \rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\ + \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ + \x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\ + \x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05ite\ + ms\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ + \x18\n\x07content\x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ ad\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\ \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\ \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orde\ diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index cd222c2868..a9fccf6d54 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -2758,11 +2758,8 @@ impl ::protobuf::reflect::ProtobufValue for RowMetaChangeset { #[derive(PartialEq,Clone,Default)] pub struct CellMeta { // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, pub field_id: ::std::string::String, - pub data: ::protobuf::SingularPtrField, - pub height: i32, + pub data: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2779,59 +2776,7 @@ impl CellMeta { ::std::default::Default::default() } - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string row_id = 2; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string field_id = 3; + // string field_id = 1; pub fn get_field_id(&self) -> &str { @@ -2857,62 +2802,35 @@ impl CellMeta { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // .AnyData data = 4; + // string data = 2; - pub fn get_data(&self) -> &AnyData { - self.data.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_data(&self) -> &str { + &self.data } pub fn clear_data(&mut self) { self.data.clear(); } - pub fn has_data(&self) -> bool { - self.data.is_some() - } - // Param is passed by value, moved - pub fn set_data(&mut self, v: AnyData) { - self.data = ::protobuf::SingularPtrField::some(v); + pub fn set_data(&mut self, v: ::std::string::String) { + self.data = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut AnyData { - if self.data.is_none() { - self.data.set_default(); - } - self.data.as_mut().unwrap() + pub fn mut_data(&mut self) -> &mut ::std::string::String { + &mut self.data } // Take field - pub fn take_data(&mut self) -> AnyData { - self.data.take().unwrap_or_else(|| AnyData::new()) - } - - // int32 height = 5; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; + pub fn take_data(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.data, ::std::string::String::new()) } } impl ::protobuf::Message for CellMeta { fn is_initialized(&self) -> bool { - for v in &self.data { - if !v.is_initialized() { - return false; - } - }; true } @@ -2921,23 +2839,10 @@ impl ::protobuf::Message for CellMeta { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 3 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, - 4 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2951,21 +2856,11 @@ impl ::protobuf::Message for CellMeta { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); + my_size += ::protobuf::rt::string_size(1, &self.field_id); } - if let Some(ref v) = self.data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if self.height != 0 { - my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); + if !self.data.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.data); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2973,22 +2868,11 @@ impl ::protobuf::Message for CellMeta { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } if !self.field_id.is_empty() { - os.write_string(3, &self.field_id)?; + os.write_string(1, &self.field_id)?; } - if let Some(ref v) = self.data.as_ref() { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if self.height != 0 { - os.write_int32(5, self.height)?; + if !self.data.is_empty() { + os.write_string(2, &self.data)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -3028,31 +2912,16 @@ impl ::protobuf::Message for CellMeta { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &CellMeta| { &m.id }, - |m: &mut CellMeta| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellMeta| { &m.row_id }, - |m: &mut CellMeta| { &mut m.row_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "field_id", |m: &CellMeta| { &m.field_id }, |m: &mut CellMeta| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "data", |m: &CellMeta| { &m.data }, |m: &mut CellMeta| { &mut m.data }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &CellMeta| { &m.height }, - |m: &mut CellMeta| { &mut m.height }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CellMeta", fields, @@ -3069,11 +2938,8 @@ impl ::protobuf::Message for CellMeta { impl ::protobuf::Clear for CellMeta { fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); self.field_id.clear(); self.data.clear(); - self.height = 0; self.unknown_fields.clear(); } } @@ -3191,14 +3057,12 @@ static file_descriptor_proto_data: &'static [u8] = b"\ field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\ - \x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\ - \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\ - \x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyD\ - ataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFi\ - eldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\ - \x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMult\ - iSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ + \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ + \x12\n\x04data\x18\x02\x20\x01(\tR\x04data*d\n\tFieldType\x12\x0c\n\x08R\ + ichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\ + \x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\ + \x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index b8577c6e3c..4e395edc92 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -13,6 +13,7 @@ message RepeatedFieldOrder { } message RowOrder { string row_id = 1; + string block_id = 2; } message RepeatedRowOrder { repeated RowOrder items = 1; @@ -26,9 +27,8 @@ message RepeatedRow { repeated Row items = 1; } message Cell { - string id = 1; - string field_id = 2; - string content = 3; + string field_id = 1; + string content = 2; } message CreateGridPayload { string name = 1; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 503284f7b5..190c400f04 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -55,11 +55,8 @@ message RowMetaChangeset { map cell_by_field_id = 4; } message CellMeta { - string id = 1; - string row_id = 2; - string field_id = 3; - AnyData data = 4; - int32 height = 5; + string field_id = 1; + string data = 2; } enum FieldType { RichText = 0; From d101509b325d1abf9da76e930825c56a25bcc64a Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 13 Mar 2022 23:16:52 +0800 Subject: [PATCH 036/179] chore: add row test --- .../rust-lib/flowy-grid/src/event_handler.rs | 6 +- .../src/services/field/field_builder.rs | 2 +- .../src/services/field/type_options.rs | 79 ++++++------- .../flowy-grid/src/services/grid_editor.rs | 35 +++--- .../src/services/grid_meta_editor.rs | 67 ++++++----- .../src/services/row/cell_stringify.rs | 14 +-- .../flowy-grid/src/services/row/mod.rs | 2 +- .../flowy-grid/src/services/row/row_loader.rs | 109 ++++++++++-------- frontend/rust-lib/flowy-grid/src/util.rs | 2 +- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 6 +- .../src/client_grid/block_pad.rs | 6 +- .../src/client_grid/grid_builder.rs | 2 +- .../src/client_grid/grid_pad.rs | 6 +- .../src/entities/grid.rs | 9 ++ .../src/entities/meta.rs | 8 +- 16 files changed, 191 insertions(+), 164 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 0861f2aaa1..22dff6e191 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); + let repeated_row: RepeatedRow = editor.get_rows(payload.row_orders).await?.into(); data_result(repeated_row) } @@ -50,10 +50,10 @@ pub(crate) async fn create_row_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( data: Data, - manager: AppData>, + _manager: AppData>, ) -> Result<(), FlowyError> { let _cell: Cell = data.into_inner(); // let editor = manager.get_grid_editor(id.as_ref())?; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 86dab02b67..8b75389ce4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -2,7 +2,7 @@ use crate::services::field::{ CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, }; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; pub struct FieldBuilder { field: Field, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index b192a1e118..080e3aaa60 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -2,12 +2,12 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; use crate::services::util::*; -use bytes::Bytes; + use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; use rust_decimal::Decimal; use rusty_money::{ iso::{Currency, CNY, EUR, USD}, @@ -25,12 +25,12 @@ pub struct RichTextDescription { impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -43,16 +43,16 @@ pub struct CheckboxDescription { impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let s = match string_to_bool(s) { true => "1", false => "0", }; - Ok(AnyData::from_str(self.field_type(), s)) + Ok(s.to_owned()) } } @@ -89,30 +89,24 @@ impl DateDescription { } impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value) { - Ok(s) => match s.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", s, e); - String::new() - } - }, + fn str_from_cell_data(&self, data: String) -> String { + match data.parse::() { + Ok(timestamp) => { + let native = NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } Err(e) => { - tracing::error!("DateDescription stringify any_data failed. {:?}", e); + tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); String::new() } } } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let timestamp = s .parse::() .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(AnyData::from_str(self.field_type(), &format!("{}", timestamp))) + Ok(format!("{}", timestamp)) } } @@ -210,12 +204,12 @@ pub struct SingleSelectDescription { impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -230,12 +224,12 @@ pub struct MultiSelectDescription { } impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -322,24 +316,17 @@ impl NumberDescription { } impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value) { - Ok(s) => match self.money_from_str(&s) { - Some(money_str) => money_str, - None => String::default(), - }, - Err(e) => { - tracing::error!("NumberDescription stringify any_data failed. {:?}", e); - String::new() - } + fn str_from_cell_data(&self, data: String) -> String { + match self.money_from_str(&data) { + Some(money_str) => money_str, + None => String::default(), } } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let strip_symbol_money = strip_money_symbol(s); let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - let money_str = decimal.to_string(); - Ok(AnyData::from_str(self.field_type(), &money_str)) + Ok(decimal.to_string()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 4b7250079e..63defcf76b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::grid_meta_editor::{ClientGridBlockMetaEditor, GridBlockMetaEditorManager}; +use crate::services::grid_meta_editor::GridBlockMetaEditorManager; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; @@ -9,13 +9,10 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedField, RepeatedFieldOrder, RepeatedRow, - RepeatedRowOrder, Row, -}; -use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; -use flowy_sync::{ - RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, + Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, }; + +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::sync::Arc; @@ -83,23 +80,29 @@ impl ClientGridEditor { pub async fn create_row(&self) -> FlowyResult<()> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; - match self.grid_meta_pad.read().await.get_blocks().last() { + let grid_block = match self.grid_meta_pad.read().await.get_blocks().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => { - let row_count = self.block_meta_manager.create_row(fields, grid_block).await?; - let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); - let _ = self.update_block(change).await?; - Ok(()) - } - } + Some(grid_block) => Ok(grid_block.clone()), + }?; + + let row_count = self.block_meta_manager.create_row(fields, &grid_block).await?; + let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); + let _ = self.update_block(change).await?; + Ok(()) } - pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; Ok(rows) } + pub async fn get_all_rows(&self) -> FlowyResult> { + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + self.block_meta_manager.get_all_rows(grid_blocks, fields).await + } + pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; for (block_id, row_count) in row_counts { diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 5358b4cde5..211af6d340 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,22 +1,20 @@ use crate::manager::GridUser; -use crate::services::row::{make_row_ids_per_block, make_rows, sort_rows, RowBuilder}; +use crate::services::row::{make_row_by_row_id, make_row_ids_per_block, make_rows, RowBuilder}; use bytes::Bytes; -use dashmap::mapref::one::Ref; + use dashmap::DashMap; use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - Field, GridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, -}; +use flowy_grid_data_model::entities::{Field, GridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset}; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, }; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; -use lib_sqlite::ConnectionPool; + use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; @@ -52,32 +50,34 @@ impl GridBlockMetaEditorManager { editor.create_row(row).await } - pub(crate) async fn delete_rows(&self, row_orders: Option) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, _row_orders: Option) -> FlowyResult> { Ok(vec![("".to_owned(), 2)]) } - pub(crate) async fn get_rows( - &self, - fields: Vec, - row_orders: Option, - ) -> FlowyResult> { - match row_orders { - None => { - let rows = vec![]; - Ok(rows) - } - Some(row_orders) => { - let row_ids_per_blocks = make_row_ids_per_block(&row_orders); - let mut rows = vec![]; - for row_ids_per_block in row_ids_per_blocks { - let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let row_metas = editor.get_rows(row_ids_per_block.row_ids).await?; - rows.extend(make_rows(&fields, row_metas)); - } - sort_rows(&mut rows, row_orders); - Ok(rows) - } + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec, fields: Vec) -> FlowyResult> { + let mut rows = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let row_metas = editor.get_rows(None).await?; + rows.extend(make_rows(&fields, row_metas)); } + Ok(rows) + } + + pub(crate) async fn get_rows(&self, fields: Vec, row_orders: RepeatedRowOrder) -> FlowyResult> { + let row_ids_per_blocks = make_row_ids_per_block(&row_orders); + let mut row_map: HashMap = HashMap::new(); + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + row_map.extend(make_row_by_row_id(&fields, row_metas)); + } + + let rows = row_orders + .iter() + .flat_map(|row_order| row_map.remove(&row_order.row_id)) + .collect::>(); + Ok(rows) } } @@ -158,9 +158,14 @@ impl ClientGridBlockMetaEditor { Ok(()) } - pub async fn get_rows(&self, row_ids: Vec) -> FlowyResult> { - let rows = self.meta_pad.read().await.get_rows(row_ids)?; - Ok(rows) + pub async fn get_rows(&self, row_ids: Option>) -> FlowyResult> { + match row_ids { + None => Ok(self.meta_pad.read().await.all_rows()), + Some(row_ids) => { + let rows = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(rows) + } + } } async fn modify(&self, f: F) -> FlowyResult<()> diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs index a75506e339..cd68038b9c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs @@ -1,15 +1,15 @@ use crate::services::field::*; -use crate::services::util::*; + use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; pub trait StringifyCellData { - fn str_from_cell_data(&self, data: AnyData) -> String; - fn str_to_cell_data(&self, s: &str) -> Result; + fn str_from_cell_data(&self, data: String) -> String; + fn str_to_cell_data(&self, s: &str) -> Result; } #[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { +pub fn stringify_serialize(field: &Field, s: &str) -> Result { match field.field_type { FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), @@ -20,8 +20,8 @@ pub fn stringify_serialize(field: &Field, s: &str) -> Result Result { - let _ = check_type_id(&data, field)?; +pub(crate) fn stringify_deserialize(data: String, field: &Field) -> Result { + // let _ = check_type_id(&data, field)?; let s = match field.field_type { FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index baac627e00..993e3401e3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -4,4 +4,4 @@ mod row_loader; pub use cell_stringify::*; pub use row_builder::*; -pub use row_loader::*; +pub(crate) use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index f9092a5d89..705871ad93 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,4 +1,6 @@ -use flowy_grid_data_model::entities::{Field, RepeatedRowOrder, Row, RowMeta}; +use crate::services::row::stringify_deserialize; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta}; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; pub(crate) struct RowIdsPerBlock { @@ -19,50 +21,67 @@ pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec>() } -pub(crate) fn sort_rows(rows: &mut Vec, row_orders: RepeatedRowOrder) { - todo!() +pub(crate) fn make_rows(fields: &Vec, row_metas: Vec) -> Vec { + let field_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let make_row = |row_meta: RowMeta| { + let cell_by_field_id = row_meta + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) + .collect::>(); + + Row { + id: row_meta.id.clone(), + cell_by_field_id, + height: row_meta.height, + } + }; + + row_metas.into_iter().map(make_row).collect::>() } -pub(crate) fn make_rows(fields: &Vec, rows: Vec) -> Vec { - // let make_cell = |field_id: String, raw_cell: CellMeta| { - // let some_field = self.field_map.get(&field_id); - // if some_field.is_none() { - // tracing::error!("Can't find the field with {}", field_id); - // return None; - // } - // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - // - // let field = some_field.unwrap(); - // match stringify_deserialize(raw_cell.data, field.value()) { - // Ok(content) => { - // let cell = Cell { - // id: raw_cell.id, - // field_id: field_id.clone(), - // content, - // }; - // Some((field_id, cell)) - // } - // Err(_) => None, - // } - // }; - // - // let rows = row_metas - // .into_par_iter() - // .map(|row_meta| { - // let mut row = Row { - // id: row_meta.id.clone(), - // cell_by_field_id: Default::default(), - // height: row_meta.height, - // }; - // row.cell_by_field_id = row_meta - // .cell_by_field_id - // .into_par_iter() - // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - // .collect::>(); - // row - // }) - // .collect::>(); - // - // Ok(rows.into()) - todo!() +#[inline(always)] +fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { + let field = field_map.get(&field_id)?; + match stringify_deserialize(raw_cell.data, field) { + Ok(content) => { + let cell = Cell::new(&field_id, content); + Some((field_id, cell)) + } + Err(e) => { + tracing::error!("{}", e); + None + } + } +} + +pub(crate) fn make_row_by_row_id(fields: &Vec, row_metas: Vec) -> HashMap { + let field_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let make_row = |row_meta: RowMeta| { + let cell_by_field_id = row_meta + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) + .collect::>(); + + let row = Row { + id: row_meta.id.clone(), + cell_by_field_id, + height: row_meta.height, + }; + (row.id.clone(), row) + }; + + row_metas + .into_par_iter() + .map(make_row) + .collect::>() } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 8cf876a052..ef6060837e 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,6 +1,6 @@ use crate::services::field::*; use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::FieldType; pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 42af2ef4c4..410e7638a5 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -169,6 +169,6 @@ async fn grid_update_block() { #[tokio::test] async fn grid_create_row() { - let scripts = vec![AssertRowCount(2), CreateRow, CreateRow, CreateRow, AssertRowCount(5)]; + let scripts = vec![AssertRowCount(3), CreateRow, CreateRow, AssertRowCount(5)]; GridEditorTest::new().await.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 277cd6b4da..278981dab3 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; +use flowy_grid_data_model::entities::{Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; -use flowy_test::event_builder::FolderEventBuilder; + use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; @@ -89,7 +89,7 @@ impl GridEditorTest { self.editor.create_row().await.unwrap(); } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_all_rows().await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index b63c667cbd..790f9f3cfa 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,5 +1,5 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; -use crate::errors::{internal_error, CollaborateError, CollaborateResult}; +use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; use lib_infra::uuid; @@ -69,6 +69,10 @@ impl GridBlockMetaPad { .collect::>()) } + pub fn all_rows(&self) -> Vec { + self.rows.iter().map(|row| (**row).clone()).collect::>() + } + pub fn number_of_rows(&self) -> i32 { self.rows.len() as i32 } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 9ba6cc7ff5..b34f55b39b 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,6 +1,6 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{Field, FieldType, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{Field, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { grid_id: String, diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 304919a310..89d2145e17 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,7 +2,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, RepeatedFieldOrder, + Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -58,7 +58,7 @@ impl GridMetaPad { pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { match field_orders { - None => Ok(self.grid_meta.fields.clone().into()), + None => Ok(self.grid_meta.fields.clone()), Some(field_orders) => { let field_by_field_id = self .grid_meta @@ -127,7 +127,7 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().find(|b| b.id == block.id).is_some() { + if grid.blocks.iter().any(|b| b.id == block.id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index d2bf2173f3..ef84bfe104 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -123,6 +123,15 @@ pub struct Cell { pub content: String, } +impl Cell { + pub fn new(field_id: &str, content: String) -> Self { + Self { + field_id: field_id.to_owned(), + content, + } + } +} + #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 2813759448..dee0a2b21b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -175,13 +175,13 @@ impl std::default::Default for FieldType { impl AsRef for FieldType { fn as_ref(&self) -> &FieldType { - &self + self } } -impl Into for &FieldType { - fn into(self) -> FieldType { - self.clone() +impl From<&FieldType> for FieldType { + fn from(field: &FieldType) -> Self { + field.clone() } } From 196d254278f76539af0c8f053defe0e0505a2f02 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 14 Mar 2022 17:24:25 +0800 Subject: [PATCH 037/179] chore: add row test --- frontend/app_flowy/lib/plugin/plugin.dart | 2 +- .../presentation/plugins/doc/document.dart | 2 +- .../flowy-grid-data-model/meta.pb.dart | 88 + .../flowy-grid-data-model/meta.pbjson.dart | 15 + .../flowy-grid/checkbox_description.pb.dart | 58 + .../checkbox_description.pbenum.dart | 7 + .../checkbox_description.pbjson.dart | 20 + .../checkbox_description.pbserver.dart | 9 + .../flowy-grid/date_description.pb.dart | 76 + .../flowy-grid/date_description.pbenum.dart | 45 + .../flowy-grid/date_description.pbjson.dart | 45 + .../flowy-grid/date_description.pbserver.dart | 9 + .../flowy-grid/number_description.pb.dart | 118 ++ .../flowy-grid/number_description.pbenum.dart | 28 + .../flowy-grid/number_description.pbjson.dart | 36 + .../number_description.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 6 +- .../flowy-grid/selection_description.pb.dart | 196 ++ .../selection_description.pbenum.dart | 7 + .../selection_description.pbjson.dart | 44 + .../selection_description.pbserver.dart | 9 + .../flowy-grid/text_description.pb.dart | 58 + .../flowy-grid/text_description.pbenum.dart | 7 + .../flowy-grid/text_description.pbjson.dart | 20 + .../flowy-grid/text_description.pbserver.dart | 9 + frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- .../protobuf/model/checkbox_description.rs | 193 ++ .../src/protobuf/model/date_description.rs | 330 ++++ .../flowy-grid/src/protobuf/model/mod.rs | 16 +- .../src/protobuf/model/number_description.rs | 401 ++++ .../protobuf/model/selection_description.rs | 692 +++++++ .../src/protobuf/model/text_description.rs | 200 ++ .../src/protobuf/model/type_options.rs | 1656 ----------------- .../protobuf/proto/checkbox_description.proto | 5 + .../src/protobuf/proto/date_description.proto | 16 + .../protobuf/proto/number_description.proto | 14 + .../proto/selection_description.proto | 15 + .../src/protobuf/proto/text_description.proto | 5 + .../src/protobuf/proto/type_options.proto | 47 - .../src/services/cell/builder/mod.rs | 137 ++ .../cell/description/checkbox_description.rs | 40 + .../cell/description/date_description.rs | 145 ++ .../src/services/cell/description/mod.rs | 11 + .../cell/description/number_description.rs | 150 ++ .../cell/description/selection_description.rs | 70 + .../cell/description/text_description.rs | 24 + .../flowy-grid/src/services/cell/mod.rs | 5 + .../src/services/field/field_builder.rs | 158 -- .../flowy-grid/src/services/field/mod.rs | 2 - .../src/services/field/type_options.rs | 390 ---- .../flowy-grid/src/services/grid_editor.rs | 129 +- .../src/services/grid_meta_editor.rs | 136 +- .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../src/services/row/cell_stringify.rs | 3 +- .../src/services/row/row_builder.rs | 58 +- .../flowy-grid/src/services/row/row_loader.rs | 8 +- .../rust-lib/flowy-grid/src/services/util.rs | 27 +- frontend/rust-lib/flowy-grid/src/util.rs | 5 +- .../flowy-grid/tests/grid/grid_test.rs | 109 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 128 +- .../src/client_grid/grid_builder.rs | 1 + .../src/client_grid/grid_pad.rs | 26 +- .../src/entities/meta.rs | 33 + .../src/protobuf/model/meta.rs | 294 ++- .../src/protobuf/proto/meta.proto | 5 + 66 files changed, 4187 insertions(+), 2425 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto delete mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/mod.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/field/type_options.rs diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index 58b428cb94..607ebaab53 100644 --- a/frontend/app_flowy/lib/plugin/plugin.dart +++ b/frontend/app_flowy/lib/plugin/plugin.dart @@ -52,7 +52,7 @@ abstract class PluginBuilder { PluginType get pluginType; - ViewDataType get dataType => ViewDataType.Block; + ViewDataType get dataType => ViewDataType.TextBlock; } abstract class PluginConfig { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart index 249d47011b..048f417de0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -50,7 +50,7 @@ class DocumentPluginBuilder extends PluginBuilder { PluginType get pluginType => DefaultPlugin.quill.type(); @override - ViewDataType get dataType => ViewDataType.Block; + ViewDataType get dataType => ViewDataType.TextBlock; } class DocumentPlugin implements Plugin { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 25104afa46..12dbec7975 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -956,3 +956,91 @@ class CellMeta extends $pb.GeneratedMessage { void clearData() => clearField(2); } +enum CellMetaChangeset_OneOfData { + data, + notSet +} + +class CellMetaChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CellMetaChangeset_OneOfData> _CellMetaChangeset_OneOfDataByTag = { + 3 : CellMetaChangeset_OneOfData.data, + 0 : CellMetaChangeset_OneOfData.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMetaChangeset', createEmptyInstance: create) + ..oo(0, [3]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..hasRequiredFields = false + ; + + CellMetaChangeset._() : super(); + factory CellMetaChangeset({ + $core.String? rowId, + $core.String? fieldId, + $core.String? data, + }) { + final _result = create(); + if (rowId != null) { + _result.rowId = rowId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (data != null) { + _result.data = data; + } + return _result; + } + factory CellMetaChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellMetaChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CellMetaChangeset clone() => CellMetaChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellMetaChangeset copyWith(void Function(CellMetaChangeset) updates) => super.copyWith((message) => updates(message as CellMetaChangeset)) as CellMetaChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellMetaChangeset create() => CellMetaChangeset._(); + CellMetaChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellMetaChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellMetaChangeset? _defaultInstance; + + CellMetaChangeset_OneOfData whichOneOfData() => _CellMetaChangeset_OneOfDataByTag[$_whichOneof(0)]!; + void clearOneOfData() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get rowId => $_getSZ(0); + @$pb.TagNumber(1) + set rowId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasRowId() => $_has(0); + @$pb.TagNumber(1) + void clearRowId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get fieldId => $_getSZ(1); + @$pb.TagNumber(2) + set fieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get data => $_getSZ(2); + @$pb.TagNumber(3) + set data($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasData() => $_has(2); + @$pb.TagNumber(3) + void clearData() => clearField(3); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 322b477e30..728367ea13 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -186,3 +186,18 @@ const CellMeta$json = const { /// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBISCgRkYXRhGAIgASgJUgRkYXRh'); +@$core.Deprecated('Use cellMetaChangesetDescriptor instead') +const CellMetaChangeset$json = const { + '1': 'CellMetaChangeset', + '2': const [ + const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'data'}, + ], + '8': const [ + const {'1': 'one_of_data'}, + ], +}; + +/// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart new file mode 100644 index 0000000000..8481b81985 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart @@ -0,0 +1,58 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class CheckboxDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxDescription', createEmptyInstance: create) + ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') + ..hasRequiredFields = false + ; + + CheckboxDescription._() : super(); + factory CheckboxDescription({ + $core.bool? isSelected, + }) { + final _result = create(); + if (isSelected != null) { + _result.isSelected = isSelected; + } + return _result; + } + factory CheckboxDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CheckboxDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CheckboxDescription clone() => CheckboxDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CheckboxDescription copyWith(void Function(CheckboxDescription) updates) => super.copyWith((message) => updates(message as CheckboxDescription)) as CheckboxDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CheckboxDescription create() => CheckboxDescription._(); + CheckboxDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CheckboxDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CheckboxDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get isSelected => $_getBF(0); + @$pb.TagNumber(1) + set isSelected($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasIsSelected() => $_has(0); + @$pb.TagNumber(1) + void clearIsSelected() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart new file mode 100644 index 0000000000..0070b08607 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart new file mode 100644 index 0000000000..6295b27033 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart @@ -0,0 +1,20 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use checkboxDescriptionDescriptor instead') +const CheckboxDescription$json = const { + '1': 'CheckboxDescription', + '2': const [ + const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, + ], +}; + +/// Descriptor for `CheckboxDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List checkboxDescriptionDescriptor = $convert.base64Decode('ChNDaGVja2JveERlc2NyaXB0aW9uEh8KC2lzX3NlbGVjdGVkGAEgASgIUgppc1NlbGVjdGVk'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart new file mode 100644 index 0000000000..166969b429 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'checkbox_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart new file mode 100644 index 0000000000..a70bff6f3c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart @@ -0,0 +1,76 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'date_description.pbenum.dart'; + +export 'date_description.pbenum.dart'; + +class DateDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values) + ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values) + ..hasRequiredFields = false + ; + + DateDescription._() : super(); + factory DateDescription({ + DateFormat? dateFormat, + TimeFormat? timeFormat, + }) { + final _result = create(); + if (dateFormat != null) { + _result.dateFormat = dateFormat; + } + if (timeFormat != null) { + _result.timeFormat = timeFormat; + } + return _result; + } + factory DateDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DateDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + DateDescription clone() => DateDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DateDescription copyWith(void Function(DateDescription) updates) => super.copyWith((message) => updates(message as DateDescription)) as DateDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static DateDescription create() => DateDescription._(); + DateDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DateDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DateDescription? _defaultInstance; + + @$pb.TagNumber(1) + DateFormat get dateFormat => $_getN(0); + @$pb.TagNumber(1) + set dateFormat(DateFormat v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasDateFormat() => $_has(0); + @$pb.TagNumber(1) + void clearDateFormat() => clearField(1); + + @$pb.TagNumber(2) + TimeFormat get timeFormat => $_getN(1); + @$pb.TagNumber(2) + set timeFormat(TimeFormat v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTimeFormat() => $_has(1); + @$pb.TagNumber(2) + void clearTimeFormat() => clearField(2); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart new file mode 100644 index 0000000000..93ea01d9be --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart @@ -0,0 +1,45 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class DateFormat extends $pb.ProtobufEnum { + static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); + static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); + static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); + static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); + + static const $core.List values = [ + Local, + US, + ISO, + Friendly, + ]; + + static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static DateFormat? valueOf($core.int value) => _byValue[value]; + + const DateFormat._($core.int v, $core.String n) : super(v, n); +} + +class TimeFormat extends $pb.ProtobufEnum { + static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); + static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); + + static const $core.List values = [ + TwelveHour, + TwentyFourHour, + ]; + + static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static TimeFormat? valueOf($core.int value) => _byValue[value]; + + const TimeFormat._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart new file mode 100644 index 0000000000..841db39005 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart @@ -0,0 +1,45 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use dateFormatDescriptor instead') +const DateFormat$json = const { + '1': 'DateFormat', + '2': const [ + const {'1': 'Local', '2': 0}, + const {'1': 'US', '2': 1}, + const {'1': 'ISO', '2': 2}, + const {'1': 'Friendly', '2': 3}, + ], +}; + +/// Descriptor for `DateFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List dateFormatDescriptor = $convert.base64Decode('CgpEYXRlRm9ybWF0EgkKBUxvY2FsEAASBgoCVVMQARIHCgNJU08QAhIMCghGcmllbmRseRAD'); +@$core.Deprecated('Use timeFormatDescriptor instead') +const TimeFormat$json = const { + '1': 'TimeFormat', + '2': const [ + const {'1': 'TwelveHour', '2': 0}, + const {'1': 'TwentyFourHour', '2': 1}, + ], +}; + +/// Descriptor for `TimeFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List timeFormatDescriptor = $convert.base64Decode('CgpUaW1lRm9ybWF0Eg4KClR3ZWx2ZUhvdXIQABISCg5Ud2VudHlGb3VySG91chAB'); +@$core.Deprecated('Use dateDescriptionDescriptor instead') +const DateDescription$json = const { + '1': 'DateDescription', + '2': const [ + const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'}, + const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'}, + ], +}; + +/// Descriptor for `DateDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List dateDescriptionDescriptor = $convert.base64Decode('Cg9EYXRlRGVzY3JpcHRpb24SLAoLZGF0ZV9mb3JtYXQYASABKA4yCy5EYXRlRm9ybWF0UgpkYXRlRm9ybWF0EiwKC3RpbWVfZm9ybWF0GAIgASgOMgsuVGltZUZvcm1hdFIKdGltZUZvcm1hdA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart new file mode 100644 index 0000000000..dd4ff2c3c7 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'date_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart new file mode 100644 index 0000000000..395ac5c07f --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart @@ -0,0 +1,118 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'number_description.pbenum.dart'; + +export 'number_description.pbenum.dart'; + +class NumberDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..hasRequiredFields = false + ; + + NumberDescription._() : super(); + factory NumberDescription({ + MoneySymbol? money, + $core.int? scale, + $core.String? symbol, + $core.bool? signPositive, + $core.String? name, + }) { + final _result = create(); + if (money != null) { + _result.money = money; + } + if (scale != null) { + _result.scale = scale; + } + if (symbol != null) { + _result.symbol = symbol; + } + if (signPositive != null) { + _result.signPositive = signPositive; + } + if (name != null) { + _result.name = name; + } + return _result; + } + factory NumberDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NumberDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NumberDescription clone() => NumberDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NumberDescription copyWith(void Function(NumberDescription) updates) => super.copyWith((message) => updates(message as NumberDescription)) as NumberDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NumberDescription create() => NumberDescription._(); + NumberDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NumberDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NumberDescription? _defaultInstance; + + @$pb.TagNumber(1) + MoneySymbol get money => $_getN(0); + @$pb.TagNumber(1) + set money(MoneySymbol v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasMoney() => $_has(0); + @$pb.TagNumber(1) + void clearMoney() => clearField(1); + + @$pb.TagNumber(2) + $core.int get scale => $_getIZ(1); + @$pb.TagNumber(2) + set scale($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasScale() => $_has(1); + @$pb.TagNumber(2) + void clearScale() => clearField(2); + + @$pb.TagNumber(3) + $core.String get symbol => $_getSZ(2); + @$pb.TagNumber(3) + set symbol($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasSymbol() => $_has(2); + @$pb.TagNumber(3) + void clearSymbol() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get signPositive => $_getBF(3); + @$pb.TagNumber(4) + set signPositive($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasSignPositive() => $_has(3); + @$pb.TagNumber(4) + void clearSignPositive() => clearField(4); + + @$pb.TagNumber(5) + $core.String get name => $_getSZ(4); + @$pb.TagNumber(5) + set name($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasName() => $_has(4); + @$pb.TagNumber(5) + void clearName() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart new file mode 100644 index 0000000000..daae771fce --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart @@ -0,0 +1,28 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class MoneySymbol extends $pb.ProtobufEnum { + static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + + static const $core.List values = [ + CNY, + EUR, + USD, + ]; + + static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); + static MoneySymbol? valueOf($core.int value) => _byValue[value]; + + const MoneySymbol._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart new file mode 100644 index 0000000000..4a0c8db75a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart @@ -0,0 +1,36 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use moneySymbolDescriptor instead') +const MoneySymbol$json = const { + '1': 'MoneySymbol', + '2': const [ + const {'1': 'CNY', '2': 0}, + const {'1': 'EUR', '2': 1}, + const {'1': 'USD', '2': 2}, + ], +}; + +/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); +@$core.Deprecated('Use numberDescriptionDescriptor instead') +const NumberDescription$json = const { + '1': 'NumberDescription', + '2': const [ + const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, + const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, + const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, + const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, + const {'1': 'name', '3': 5, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart new file mode 100644 index 0000000000..58225a92b7 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'number_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index b7eb77d660..0ad090edd5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -1,3 +1,7 @@ // Auto-generated, do not edit -export './type_options.pb.dart'; +export './date_description.pb.dart'; +export './text_description.pb.dart'; +export './checkbox_description.pb.dart'; +export './selection_description.pb.dart'; export './event_map.pb.dart'; +export './number_description.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart new file mode 100644 index 0000000000..27b2fa8431 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart @@ -0,0 +1,196 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class SingleSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + SingleSelectDescription._() : super(); + factory SingleSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory SingleSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SingleSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SingleSelectDescription clone() => SingleSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SingleSelectDescription copyWith(void Function(SingleSelectDescription) updates) => super.copyWith((message) => updates(message as SingleSelectDescription)) as SingleSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SingleSelectDescription create() => SingleSelectDescription._(); + SingleSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SingleSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SingleSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class MultiSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + MultiSelectDescription._() : super(); + factory MultiSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory MultiSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MultiSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MultiSelectDescription clone() => MultiSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MultiSelectDescription copyWith(void Function(MultiSelectDescription) updates) => super.copyWith((message) => updates(message as MultiSelectDescription)) as MultiSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MultiSelectDescription create() => MultiSelectDescription._(); + MultiSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MultiSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MultiSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class SelectOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') + ..hasRequiredFields = false + ; + + SelectOption._() : super(); + factory SelectOption({ + $core.String? id, + $core.String? name, + $core.String? color, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (color != null) { + _result.color = color; + } + return _result; + } + factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SelectOption clone() => SelectOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOption create() => SelectOption._(); + SelectOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get color => $_getSZ(2); + @$pb.TagNumber(3) + set color($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasColor() => $_has(2); + @$pb.TagNumber(3) + void clearColor() => clearField(3); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart new file mode 100644 index 0000000000..6688bc34c9 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart new file mode 100644 index 0000000000..6bb0c9e4db --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart @@ -0,0 +1,44 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use singleSelectDescriptionDescriptor instead') +const SingleSelectDescription$json = const { + '1': 'SingleSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `SingleSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List singleSelectDescriptionDescriptor = $convert.base64Decode('ChdTaW5nbGVTZWxlY3REZXNjcmlwdGlvbhInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); +@$core.Deprecated('Use multiSelectDescriptionDescriptor instead') +const MultiSelectDescription$json = const { + '1': 'MultiSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `MultiSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List multiSelectDescriptionDescriptor = $convert.base64Decode('ChZNdWx0aVNlbGVjdERlc2NyaXB0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); +@$core.Deprecated('Use selectOptionDescriptor instead') +const SelectOption$json = const { + '1': 'SelectOption', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, + ], +}; + +/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart new file mode 100644 index 0000000000..f55cbba1ec --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'selection_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart new file mode 100644 index 0000000000..9434b2fc90 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart @@ -0,0 +1,58 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class RichTextDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextDescription', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') + ..hasRequiredFields = false + ; + + RichTextDescription._() : super(); + factory RichTextDescription({ + $core.String? format, + }) { + final _result = create(); + if (format != null) { + _result.format = format; + } + return _result; + } + factory RichTextDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RichTextDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RichTextDescription clone() => RichTextDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RichTextDescription copyWith(void Function(RichTextDescription) updates) => super.copyWith((message) => updates(message as RichTextDescription)) as RichTextDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RichTextDescription create() => RichTextDescription._(); + RichTextDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RichTextDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RichTextDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get format => $_getSZ(0); + @$pb.TagNumber(1) + set format($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFormat() => $_has(0); + @$pb.TagNumber(1) + void clearFormat() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart new file mode 100644 index 0000000000..e01054c586 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart new file mode 100644 index 0000000000..fdf2098d47 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart @@ -0,0 +1,20 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use richTextDescriptionDescriptor instead') +const RichTextDescription$json = const { + '1': 'RichTextDescription', + '2': const [ + const {'1': 'format', '3': 1, '4': 1, '5': 9, '10': 'format'}, + ], +}; + +/// Descriptor for `RichTextDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List richTextDescriptionDescriptor = $convert.base64Decode('ChNSaWNoVGV4dERlc2NyaXB0aW9uEhYKBmZvcm1hdBgBIAEoCVIGZm9ybWF0'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart new file mode 100644 index 0000000000..2a02dd56b1 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'text_description.pb.dart'; + diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index fc5c01c773..4d1a277df3 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/field/type_options.rs"] +proto_crates = ["src/event_map.rs", "src/services/cell/description"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 22dff6e191..5aa786431b 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(payload.row_orders).await?.into(); + let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); data_result(repeated_row) } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs new file mode 100644 index 0000000000..276617efbd --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs @@ -0,0 +1,193 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `checkbox_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct CheckboxDescription { + // message fields + pub is_selected: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CheckboxDescription { + fn default() -> &'a CheckboxDescription { + ::default_instance() + } +} + +impl CheckboxDescription { + pub fn new() -> CheckboxDescription { + ::std::default::Default::default() + } + + // bool is_selected = 1; + + + pub fn get_is_selected(&self) -> bool { + self.is_selected + } + pub fn clear_is_selected(&mut self) { + self.is_selected = false; + } + + // Param is passed by value, moved + pub fn set_is_selected(&mut self, v: bool) { + self.is_selected = v; + } +} + +impl ::protobuf::Message for CheckboxDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.is_selected = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.is_selected != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.is_selected != false { + os.write_bool(1, self.is_selected)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CheckboxDescription { + CheckboxDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "is_selected", + |m: &CheckboxDescription| { &m.is_selected }, + |m: &mut CheckboxDescription| { &mut m.is_selected }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CheckboxDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CheckboxDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CheckboxDescription::new) + } +} + +impl ::protobuf::Clear for CheckboxDescription { + fn clear(&mut self) { + self.is_selected = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CheckboxDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CheckboxDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1acheckbox_description.proto\"6\n\x13CheckboxDescription\x12\x1f\n\ + \x0bis_selected\x18\x01\x20\x01(\x08R\nisSelectedb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs new file mode 100644 index 0000000000..05b2bc6a0f --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs @@ -0,0 +1,330 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `date_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct DateDescription { + // message fields + pub date_format: DateFormat, + pub time_format: TimeFormat, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a DateDescription { + fn default() -> &'a DateDescription { + ::default_instance() + } +} + +impl DateDescription { + pub fn new() -> DateDescription { + ::std::default::Default::default() + } + + // .DateFormat date_format = 1; + + + pub fn get_date_format(&self) -> DateFormat { + self.date_format + } + pub fn clear_date_format(&mut self) { + self.date_format = DateFormat::Local; + } + + // Param is passed by value, moved + pub fn set_date_format(&mut self, v: DateFormat) { + self.date_format = v; + } + + // .TimeFormat time_format = 2; + + + pub fn get_time_format(&self) -> TimeFormat { + self.time_format + } + pub fn clear_time_format(&mut self) { + self.time_format = TimeFormat::TwelveHour; + } + + // Param is passed by value, moved + pub fn set_time_format(&mut self, v: TimeFormat) { + self.time_format = v; + } +} + +impl ::protobuf::Message for DateDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.date_format, 1, &mut self.unknown_fields)? + }, + 2 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.time_format, 2, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.date_format != DateFormat::Local { + my_size += ::protobuf::rt::enum_size(1, self.date_format); + } + if self.time_format != TimeFormat::TwelveHour { + my_size += ::protobuf::rt::enum_size(2, self.time_format); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.date_format != DateFormat::Local { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.date_format))?; + } + if self.time_format != TimeFormat::TwelveHour { + os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.time_format))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> DateDescription { + DateDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "date_format", + |m: &DateDescription| { &m.date_format }, + |m: &mut DateDescription| { &mut m.date_format }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "time_format", + |m: &DateDescription| { &m.time_format }, + |m: &mut DateDescription| { &mut m.time_format }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "DateDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static DateDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(DateDescription::new) + } +} + +impl ::protobuf::Clear for DateDescription { + fn clear(&mut self) { + self.date_format = DateFormat::Local; + self.time_format = TimeFormat::TwelveHour; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for DateDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for DateDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum DateFormat { + Local = 0, + US = 1, + ISO = 2, + Friendly = 3, +} + +impl ::protobuf::ProtobufEnum for DateFormat { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(DateFormat::Local), + 1 => ::std::option::Option::Some(DateFormat::US), + 2 => ::std::option::Option::Some(DateFormat::ISO), + 3 => ::std::option::Option::Some(DateFormat::Friendly), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [DateFormat] = &[ + DateFormat::Local, + DateFormat::US, + DateFormat::ISO, + DateFormat::Friendly, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("DateFormat", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for DateFormat { +} + +impl ::std::default::Default for DateFormat { + fn default() -> Self { + DateFormat::Local + } +} + +impl ::protobuf::reflect::ProtobufValue for DateFormat { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum TimeFormat { + TwelveHour = 0, + TwentyFourHour = 1, +} + +impl ::protobuf::ProtobufEnum for TimeFormat { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(TimeFormat::TwelveHour), + 1 => ::std::option::Option::Some(TimeFormat::TwentyFourHour), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [TimeFormat] = &[ + TimeFormat::TwelveHour, + TimeFormat::TwentyFourHour, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("TimeFormat", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for TimeFormat { +} + +impl ::std::default::Default for TimeFormat { + fn default() -> Self { + TimeFormat::TwelveHour + } +} + +impl ::protobuf::reflect::ProtobufValue for TimeFormat { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x16date_description.proto\"m\n\x0fDateDescription\x12,\n\x0bdate_form\ + at\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btime_form\ + at\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat*6\n\nDateFormat\x12\ + \t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\ + \x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\ + \x12\x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index d9c75efb74..fb32dca3f2 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,8 +1,20 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit -mod type_options; -pub use type_options::*; +mod date_description; +pub use date_description::*; + +mod text_description; +pub use text_description::*; + +mod checkbox_description; +pub use checkbox_description::*; + +mod selection_description; +pub use selection_description::*; mod event_map; pub use event_map::*; + +mod number_description; +pub use number_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs new file mode 100644 index 0000000000..17bdb557e6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs @@ -0,0 +1,401 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `number_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct NumberDescription { + // message fields + pub money: MoneySymbol, + pub scale: u32, + pub symbol: ::std::string::String, + pub sign_positive: bool, + pub name: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a NumberDescription { + fn default() -> &'a NumberDescription { + ::default_instance() + } +} + +impl NumberDescription { + pub fn new() -> NumberDescription { + ::std::default::Default::default() + } + + // .MoneySymbol money = 1; + + + pub fn get_money(&self) -> MoneySymbol { + self.money + } + pub fn clear_money(&mut self) { + self.money = MoneySymbol::CNY; + } + + // Param is passed by value, moved + pub fn set_money(&mut self, v: MoneySymbol) { + self.money = v; + } + + // uint32 scale = 2; + + + pub fn get_scale(&self) -> u32 { + self.scale + } + pub fn clear_scale(&mut self) { + self.scale = 0; + } + + // Param is passed by value, moved + pub fn set_scale(&mut self, v: u32) { + self.scale = v; + } + + // string symbol = 3; + + + pub fn get_symbol(&self) -> &str { + &self.symbol + } + pub fn clear_symbol(&mut self) { + self.symbol.clear(); + } + + // Param is passed by value, moved + pub fn set_symbol(&mut self, v: ::std::string::String) { + self.symbol = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_symbol(&mut self) -> &mut ::std::string::String { + &mut self.symbol + } + + // Take field + pub fn take_symbol(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.symbol, ::std::string::String::new()) + } + + // bool sign_positive = 4; + + + pub fn get_sign_positive(&self) -> bool { + self.sign_positive + } + pub fn clear_sign_positive(&mut self) { + self.sign_positive = false; + } + + // Param is passed by value, moved + pub fn set_sign_positive(&mut self, v: bool) { + self.sign_positive = v; + } + + // string name = 5; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for NumberDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.money, 1, &mut self.unknown_fields)? + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint32()?; + self.scale = tmp; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.symbol)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.sign_positive = tmp; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.money != MoneySymbol::CNY { + my_size += ::protobuf::rt::enum_size(1, self.money); + } + if self.scale != 0 { + my_size += ::protobuf::rt::value_size(2, self.scale, ::protobuf::wire_format::WireTypeVarint); + } + if !self.symbol.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.symbol); + } + if self.sign_positive != false { + my_size += 2; + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.name); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.money != MoneySymbol::CNY { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; + } + if self.scale != 0 { + os.write_uint32(2, self.scale)?; + } + if !self.symbol.is_empty() { + os.write_string(3, &self.symbol)?; + } + if self.sign_positive != false { + os.write_bool(4, self.sign_positive)?; + } + if !self.name.is_empty() { + os.write_string(5, &self.name)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> NumberDescription { + NumberDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "money", + |m: &NumberDescription| { &m.money }, + |m: &mut NumberDescription| { &mut m.money }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( + "scale", + |m: &NumberDescription| { &m.scale }, + |m: &mut NumberDescription| { &mut m.scale }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "symbol", + |m: &NumberDescription| { &m.symbol }, + |m: &mut NumberDescription| { &mut m.symbol }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "sign_positive", + |m: &NumberDescription| { &m.sign_positive }, + |m: &mut NumberDescription| { &mut m.sign_positive }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &NumberDescription| { &m.name }, + |m: &mut NumberDescription| { &mut m.name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "NumberDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static NumberDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(NumberDescription::new) + } +} + +impl ::protobuf::Clear for NumberDescription { + fn clear(&mut self) { + self.money = MoneySymbol::CNY; + self.scale = 0; + self.symbol.clear(); + self.sign_positive = false; + self.name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for NumberDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for NumberDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum MoneySymbol { + CNY = 0, + EUR = 1, + USD = 2, +} + +impl ::protobuf::ProtobufEnum for MoneySymbol { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(MoneySymbol::CNY), + 1 => ::std::option::Option::Some(MoneySymbol::EUR), + 2 => ::std::option::Option::Some(MoneySymbol::USD), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [MoneySymbol] = &[ + MoneySymbol::CNY, + MoneySymbol::EUR, + MoneySymbol::USD, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for MoneySymbol { +} + +impl ::std::default::Default for MoneySymbol { + fn default() -> Self { + MoneySymbol::CNY + } +} + +impl ::protobuf::reflect::ProtobufValue for MoneySymbol { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x18number_description.proto\"\x9e\x01\n\x11NumberDescription\x12\"\n\ + \x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05money\x12\x14\n\x05s\ + cale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\t\ + R\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositive\ + \x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*(\n\x0bMoneySymbol\x12\ + \x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\x02b\ + \x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs new file mode 100644 index 0000000000..9feda09402 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs @@ -0,0 +1,692 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `selection_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct SingleSelectDescription { + // message fields + pub options: ::protobuf::RepeatedField, + pub disable_color: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SingleSelectDescription { + fn default() -> &'a SingleSelectDescription { + ::default_instance() + } +} + +impl SingleSelectDescription { + pub fn new() -> SingleSelectDescription { + ::std::default::Default::default() + } + + // repeated .SelectOption options = 1; + + + pub fn get_options(&self) -> &[SelectOption] { + &self.options + } + pub fn clear_options(&mut self) { + self.options.clear(); + } + + // Param is passed by value, moved + pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { + self.options = v; + } + + // Mutable pointer to the field. + pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.options + } + + // Take field + pub fn take_options(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) + } + + // bool disable_color = 2; + + + pub fn get_disable_color(&self) -> bool { + self.disable_color + } + pub fn clear_disable_color(&mut self) { + self.disable_color = false; + } + + // Param is passed by value, moved + pub fn set_disable_color(&mut self, v: bool) { + self.disable_color = v; + } +} + +impl ::protobuf::Message for SingleSelectDescription { + fn is_initialized(&self) -> bool { + for v in &self.options { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.disable_color = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.options { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if self.disable_color != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.options { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if self.disable_color != false { + os.write_bool(2, self.disable_color)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SingleSelectDescription { + SingleSelectDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "options", + |m: &SingleSelectDescription| { &m.options }, + |m: &mut SingleSelectDescription| { &mut m.options }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "disable_color", + |m: &SingleSelectDescription| { &m.disable_color }, + |m: &mut SingleSelectDescription| { &mut m.disable_color }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SingleSelectDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SingleSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SingleSelectDescription::new) + } +} + +impl ::protobuf::Clear for SingleSelectDescription { + fn clear(&mut self) { + self.options.clear(); + self.disable_color = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SingleSelectDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MultiSelectDescription { + // message fields + pub options: ::protobuf::RepeatedField, + pub disable_color: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MultiSelectDescription { + fn default() -> &'a MultiSelectDescription { + ::default_instance() + } +} + +impl MultiSelectDescription { + pub fn new() -> MultiSelectDescription { + ::std::default::Default::default() + } + + // repeated .SelectOption options = 1; + + + pub fn get_options(&self) -> &[SelectOption] { + &self.options + } + pub fn clear_options(&mut self) { + self.options.clear(); + } + + // Param is passed by value, moved + pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { + self.options = v; + } + + // Mutable pointer to the field. + pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.options + } + + // Take field + pub fn take_options(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) + } + + // bool disable_color = 2; + + + pub fn get_disable_color(&self) -> bool { + self.disable_color + } + pub fn clear_disable_color(&mut self) { + self.disable_color = false; + } + + // Param is passed by value, moved + pub fn set_disable_color(&mut self, v: bool) { + self.disable_color = v; + } +} + +impl ::protobuf::Message for MultiSelectDescription { + fn is_initialized(&self) -> bool { + for v in &self.options { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.disable_color = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.options { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if self.disable_color != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.options { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if self.disable_color != false { + os.write_bool(2, self.disable_color)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MultiSelectDescription { + MultiSelectDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "options", + |m: &MultiSelectDescription| { &m.options }, + |m: &mut MultiSelectDescription| { &mut m.options }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "disable_color", + |m: &MultiSelectDescription| { &m.disable_color }, + |m: &mut MultiSelectDescription| { &mut m.disable_color }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MultiSelectDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MultiSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MultiSelectDescription::new) + } +} + +impl ::protobuf::Clear for MultiSelectDescription { + fn clear(&mut self) { + self.options.clear(); + self.disable_color = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MultiSelectDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SelectOption { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub color: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOption { + fn default() -> &'a SelectOption { + ::default_instance() + } +} + +impl SelectOption { + pub fn new() -> SelectOption { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string color = 3; + + + pub fn get_color(&self) -> &str { + &self.color + } + pub fn clear_color(&mut self) { + self.color.clear(); + } + + // Param is passed by value, moved + pub fn set_color(&mut self, v: ::std::string::String) { + self.color = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_color(&mut self) -> &mut ::std::string::String { + &mut self.color + } + + // Take field + pub fn take_color(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.color, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for SelectOption { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.color)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.name); + } + if !self.color.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.color); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.name.is_empty() { + os.write_string(2, &self.name)?; + } + if !self.color.is_empty() { + os.write_string(3, &self.color)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SelectOption { + SelectOption::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &SelectOption| { &m.id }, + |m: &mut SelectOption| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &SelectOption| { &m.name }, + |m: &mut SelectOption| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "color", + |m: &SelectOption| { &m.color }, + |m: &mut SelectOption| { &mut m.color }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOption", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOption::new) + } +} + +impl ::protobuf::Clear for SelectOption { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.color.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOption { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOption { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1bselection_description.proto\"g\n\x17SingleSelectDescription\x12'\n\ + \x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdis\ + able_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"f\n\x16MultiSelectDesc\ + ription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07optio\ + ns\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cS\ + electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ + \x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05c\ + olorb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs new file mode 100644 index 0000000000..ca2d720e14 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs @@ -0,0 +1,200 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `text_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct RichTextDescription { + // message fields + pub format: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RichTextDescription { + fn default() -> &'a RichTextDescription { + ::default_instance() + } +} + +impl RichTextDescription { + pub fn new() -> RichTextDescription { + ::std::default::Default::default() + } + + // string format = 1; + + + pub fn get_format(&self) -> &str { + &self.format + } + pub fn clear_format(&mut self) { + self.format.clear(); + } + + // Param is passed by value, moved + pub fn set_format(&mut self, v: ::std::string::String) { + self.format = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_format(&mut self) -> &mut ::std::string::String { + &mut self.format + } + + // Take field + pub fn take_format(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.format, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for RichTextDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.format)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.format.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.format); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.format.is_empty() { + os.write_string(1, &self.format)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RichTextDescription { + RichTextDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "format", + |m: &RichTextDescription| { &m.format }, + |m: &mut RichTextDescription| { &mut m.format }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RichTextDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RichTextDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RichTextDescription::new) + } +} + +impl ::protobuf::Clear for RichTextDescription { + fn clear(&mut self) { + self.format.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RichTextDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RichTextDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x16text_description.proto\"-\n\x13RichTextDescription\x12\x16\n\x06fo\ + rmat\x18\x01\x20\x01(\tR\x06formatb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs deleted file mode 100644 index cda2c556c3..0000000000 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs +++ /dev/null @@ -1,1656 +0,0 @@ -// This file is generated by rust-protobuf 2.25.2. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![cfg_attr(rustfmt, rustfmt::skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `type_options.proto` - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; - -#[derive(PartialEq,Clone,Default)] -pub struct RichTextDescription { - // message fields - pub format: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RichTextDescription { - fn default() -> &'a RichTextDescription { - ::default_instance() - } -} - -impl RichTextDescription { - pub fn new() -> RichTextDescription { - ::std::default::Default::default() - } - - // string format = 1; - - - pub fn get_format(&self) -> &str { - &self.format - } - pub fn clear_format(&mut self) { - self.format.clear(); - } - - // Param is passed by value, moved - pub fn set_format(&mut self, v: ::std::string::String) { - self.format = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_format(&mut self) -> &mut ::std::string::String { - &mut self.format - } - - // Take field - pub fn take_format(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.format, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for RichTextDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.format)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.format.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.format); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.format.is_empty() { - os.write_string(1, &self.format)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RichTextDescription { - RichTextDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "format", - |m: &RichTextDescription| { &m.format }, - |m: &mut RichTextDescription| { &mut m.format }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RichTextDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RichTextDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RichTextDescription::new) - } -} - -impl ::protobuf::Clear for RichTextDescription { - fn clear(&mut self) { - self.format.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RichTextDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RichTextDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct CheckboxDescription { - // message fields - pub is_selected: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CheckboxDescription { - fn default() -> &'a CheckboxDescription { - ::default_instance() - } -} - -impl CheckboxDescription { - pub fn new() -> CheckboxDescription { - ::std::default::Default::default() - } - - // bool is_selected = 1; - - - pub fn get_is_selected(&self) -> bool { - self.is_selected - } - pub fn clear_is_selected(&mut self) { - self.is_selected = false; - } - - // Param is passed by value, moved - pub fn set_is_selected(&mut self, v: bool) { - self.is_selected = v; - } -} - -impl ::protobuf::Message for CheckboxDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.is_selected = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.is_selected != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.is_selected != false { - os.write_bool(1, self.is_selected)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CheckboxDescription { - CheckboxDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "is_selected", - |m: &CheckboxDescription| { &m.is_selected }, - |m: &mut CheckboxDescription| { &mut m.is_selected }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CheckboxDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CheckboxDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CheckboxDescription::new) - } -} - -impl ::protobuf::Clear for CheckboxDescription { - fn clear(&mut self) { - self.is_selected = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CheckboxDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CheckboxDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct DateDescription { - // message fields - pub date_format: DateFormat, - pub time_format: TimeFormat, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a DateDescription { - fn default() -> &'a DateDescription { - ::default_instance() - } -} - -impl DateDescription { - pub fn new() -> DateDescription { - ::std::default::Default::default() - } - - // .DateFormat date_format = 1; - - - pub fn get_date_format(&self) -> DateFormat { - self.date_format - } - pub fn clear_date_format(&mut self) { - self.date_format = DateFormat::Local; - } - - // Param is passed by value, moved - pub fn set_date_format(&mut self, v: DateFormat) { - self.date_format = v; - } - - // .TimeFormat time_format = 2; - - - pub fn get_time_format(&self) -> TimeFormat { - self.time_format - } - pub fn clear_time_format(&mut self) { - self.time_format = TimeFormat::TwelveHour; - } - - // Param is passed by value, moved - pub fn set_time_format(&mut self, v: TimeFormat) { - self.time_format = v; - } -} - -impl ::protobuf::Message for DateDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.date_format, 1, &mut self.unknown_fields)? - }, - 2 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.time_format, 2, &mut self.unknown_fields)? - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.date_format != DateFormat::Local { - my_size += ::protobuf::rt::enum_size(1, self.date_format); - } - if self.time_format != TimeFormat::TwelveHour { - my_size += ::protobuf::rt::enum_size(2, self.time_format); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.date_format != DateFormat::Local { - os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.date_format))?; - } - if self.time_format != TimeFormat::TwelveHour { - os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.time_format))?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> DateDescription { - DateDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "date_format", - |m: &DateDescription| { &m.date_format }, - |m: &mut DateDescription| { &mut m.date_format }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "time_format", - |m: &DateDescription| { &m.time_format }, - |m: &mut DateDescription| { &mut m.time_format }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "DateDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static DateDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(DateDescription::new) - } -} - -impl ::protobuf::Clear for DateDescription { - fn clear(&mut self) { - self.date_format = DateFormat::Local; - self.time_format = TimeFormat::TwelveHour; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for DateDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for DateDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct SingleSelectDescription { - // message fields - pub options: ::protobuf::RepeatedField, - pub disable_color: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SingleSelectDescription { - fn default() -> &'a SingleSelectDescription { - ::default_instance() - } -} - -impl SingleSelectDescription { - pub fn new() -> SingleSelectDescription { - ::std::default::Default::default() - } - - // repeated .SelectOption options = 1; - - - pub fn get_options(&self) -> &[SelectOption] { - &self.options - } - pub fn clear_options(&mut self) { - self.options.clear(); - } - - // Param is passed by value, moved - pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { - self.options = v; - } - - // Mutable pointer to the field. - pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.options - } - - // Take field - pub fn take_options(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) - } - - // bool disable_color = 2; - - - pub fn get_disable_color(&self) -> bool { - self.disable_color - } - pub fn clear_disable_color(&mut self) { - self.disable_color = false; - } - - // Param is passed by value, moved - pub fn set_disable_color(&mut self, v: bool) { - self.disable_color = v; - } -} - -impl ::protobuf::Message for SingleSelectDescription { - fn is_initialized(&self) -> bool { - for v in &self.options { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.disable_color = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.options { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - if self.disable_color != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.options { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - if self.disable_color != false { - os.write_bool(2, self.disable_color)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> SingleSelectDescription { - SingleSelectDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "options", - |m: &SingleSelectDescription| { &m.options }, - |m: &mut SingleSelectDescription| { &mut m.options }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "disable_color", - |m: &SingleSelectDescription| { &m.disable_color }, - |m: &mut SingleSelectDescription| { &mut m.disable_color }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SingleSelectDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SingleSelectDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SingleSelectDescription::new) - } -} - -impl ::protobuf::Clear for SingleSelectDescription { - fn clear(&mut self) { - self.options.clear(); - self.disable_color = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SingleSelectDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct MultiSelectDescription { - // message fields - pub options: ::protobuf::RepeatedField, - pub disable_color: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a MultiSelectDescription { - fn default() -> &'a MultiSelectDescription { - ::default_instance() - } -} - -impl MultiSelectDescription { - pub fn new() -> MultiSelectDescription { - ::std::default::Default::default() - } - - // repeated .SelectOption options = 1; - - - pub fn get_options(&self) -> &[SelectOption] { - &self.options - } - pub fn clear_options(&mut self) { - self.options.clear(); - } - - // Param is passed by value, moved - pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { - self.options = v; - } - - // Mutable pointer to the field. - pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.options - } - - // Take field - pub fn take_options(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) - } - - // bool disable_color = 2; - - - pub fn get_disable_color(&self) -> bool { - self.disable_color - } - pub fn clear_disable_color(&mut self) { - self.disable_color = false; - } - - // Param is passed by value, moved - pub fn set_disable_color(&mut self, v: bool) { - self.disable_color = v; - } -} - -impl ::protobuf::Message for MultiSelectDescription { - fn is_initialized(&self) -> bool { - for v in &self.options { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.disable_color = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.options { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - if self.disable_color != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.options { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - if self.disable_color != false { - os.write_bool(2, self.disable_color)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> MultiSelectDescription { - MultiSelectDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "options", - |m: &MultiSelectDescription| { &m.options }, - |m: &mut MultiSelectDescription| { &mut m.options }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "disable_color", - |m: &MultiSelectDescription| { &m.disable_color }, - |m: &mut MultiSelectDescription| { &mut m.disable_color }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "MultiSelectDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static MultiSelectDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(MultiSelectDescription::new) - } -} - -impl ::protobuf::Clear for MultiSelectDescription { - fn clear(&mut self) { - self.options.clear(); - self.disable_color = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for MultiSelectDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct SelectOption { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub color: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SelectOption { - fn default() -> &'a SelectOption { - ::default_instance() - } -} - -impl SelectOption { - pub fn new() -> SelectOption { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string name = 2; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // string color = 3; - - - pub fn get_color(&self) -> &str { - &self.color - } - pub fn clear_color(&mut self) { - self.color.clear(); - } - - // Param is passed by value, moved - pub fn set_color(&mut self, v: ::std::string::String) { - self.color = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_color(&mut self) -> &mut ::std::string::String { - &mut self.color - } - - // Take field - pub fn take_color(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.color, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for SelectOption { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.color)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.name); - } - if !self.color.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.color); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.name.is_empty() { - os.write_string(2, &self.name)?; - } - if !self.color.is_empty() { - os.write_string(3, &self.color)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> SelectOption { - SelectOption::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &SelectOption| { &m.id }, - |m: &mut SelectOption| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &SelectOption| { &m.name }, - |m: &mut SelectOption| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "color", - |m: &SelectOption| { &m.color }, - |m: &mut SelectOption| { &mut m.color }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOption", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SelectOption { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOption::new) - } -} - -impl ::protobuf::Clear for SelectOption { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.color.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SelectOption { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOption { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct NumberDescription { - // message fields - pub money: MoneySymbol, - pub scale: u32, - pub symbol: ::std::string::String, - pub sign_positive: bool, - pub name: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a NumberDescription { - fn default() -> &'a NumberDescription { - ::default_instance() - } -} - -impl NumberDescription { - pub fn new() -> NumberDescription { - ::std::default::Default::default() - } - - // .MoneySymbol money = 1; - - - pub fn get_money(&self) -> MoneySymbol { - self.money - } - pub fn clear_money(&mut self) { - self.money = MoneySymbol::CNY; - } - - // Param is passed by value, moved - pub fn set_money(&mut self, v: MoneySymbol) { - self.money = v; - } - - // uint32 scale = 2; - - - pub fn get_scale(&self) -> u32 { - self.scale - } - pub fn clear_scale(&mut self) { - self.scale = 0; - } - - // Param is passed by value, moved - pub fn set_scale(&mut self, v: u32) { - self.scale = v; - } - - // string symbol = 3; - - - pub fn get_symbol(&self) -> &str { - &self.symbol - } - pub fn clear_symbol(&mut self) { - self.symbol.clear(); - } - - // Param is passed by value, moved - pub fn set_symbol(&mut self, v: ::std::string::String) { - self.symbol = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_symbol(&mut self) -> &mut ::std::string::String { - &mut self.symbol - } - - // Take field - pub fn take_symbol(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.symbol, ::std::string::String::new()) - } - - // bool sign_positive = 4; - - - pub fn get_sign_positive(&self) -> bool { - self.sign_positive - } - pub fn clear_sign_positive(&mut self) { - self.sign_positive = false; - } - - // Param is passed by value, moved - pub fn set_sign_positive(&mut self, v: bool) { - self.sign_positive = v; - } - - // string name = 5; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for NumberDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.money, 1, &mut self.unknown_fields)? - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_uint32()?; - self.scale = tmp; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.symbol)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.sign_positive = tmp; - }, - 5 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.money != MoneySymbol::CNY { - my_size += ::protobuf::rt::enum_size(1, self.money); - } - if self.scale != 0 { - my_size += ::protobuf::rt::value_size(2, self.scale, ::protobuf::wire_format::WireTypeVarint); - } - if !self.symbol.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.symbol); - } - if self.sign_positive != false { - my_size += 2; - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(5, &self.name); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.money != MoneySymbol::CNY { - os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; - } - if self.scale != 0 { - os.write_uint32(2, self.scale)?; - } - if !self.symbol.is_empty() { - os.write_string(3, &self.symbol)?; - } - if self.sign_positive != false { - os.write_bool(4, self.sign_positive)?; - } - if !self.name.is_empty() { - os.write_string(5, &self.name)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> NumberDescription { - NumberDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "money", - |m: &NumberDescription| { &m.money }, - |m: &mut NumberDescription| { &mut m.money }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( - "scale", - |m: &NumberDescription| { &m.scale }, - |m: &mut NumberDescription| { &mut m.scale }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "symbol", - |m: &NumberDescription| { &m.symbol }, - |m: &mut NumberDescription| { &mut m.symbol }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "sign_positive", - |m: &NumberDescription| { &m.sign_positive }, - |m: &mut NumberDescription| { &mut m.sign_positive }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &NumberDescription| { &m.name }, - |m: &mut NumberDescription| { &mut m.name }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "NumberDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static NumberDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(NumberDescription::new) - } -} - -impl ::protobuf::Clear for NumberDescription { - fn clear(&mut self) { - self.money = MoneySymbol::CNY; - self.scale = 0; - self.symbol.clear(); - self.sign_positive = false; - self.name.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for NumberDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for NumberDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum DateFormat { - Local = 0, - US = 1, - ISO = 2, - Friendly = 3, -} - -impl ::protobuf::ProtobufEnum for DateFormat { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(DateFormat::Local), - 1 => ::std::option::Option::Some(DateFormat::US), - 2 => ::std::option::Option::Some(DateFormat::ISO), - 3 => ::std::option::Option::Some(DateFormat::Friendly), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [DateFormat] = &[ - DateFormat::Local, - DateFormat::US, - DateFormat::ISO, - DateFormat::Friendly, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("DateFormat", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for DateFormat { -} - -impl ::std::default::Default for DateFormat { - fn default() -> Self { - DateFormat::Local - } -} - -impl ::protobuf::reflect::ProtobufValue for DateFormat { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum TimeFormat { - TwelveHour = 0, - TwentyFourHour = 1, -} - -impl ::protobuf::ProtobufEnum for TimeFormat { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(TimeFormat::TwelveHour), - 1 => ::std::option::Option::Some(TimeFormat::TwentyFourHour), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [TimeFormat] = &[ - TimeFormat::TwelveHour, - TimeFormat::TwentyFourHour, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("TimeFormat", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for TimeFormat { -} - -impl ::std::default::Default for TimeFormat { - fn default() -> Self { - TimeFormat::TwelveHour - } -} - -impl ::protobuf::reflect::ProtobufValue for TimeFormat { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, -} - -impl ::protobuf::ProtobufEnum for MoneySymbol { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(MoneySymbol::CNY), - 1 => ::std::option::Option::Some(MoneySymbol::EUR), - 2 => ::std::option::Option::Some(MoneySymbol::USD), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [MoneySymbol] = &[ - MoneySymbol::CNY, - MoneySymbol::EUR, - MoneySymbol::USD, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for MoneySymbol { -} - -impl ::std::default::Default for MoneySymbol { - fn default() -> Self { - MoneySymbol::CNY - } -} - -impl ::protobuf::reflect::ProtobufValue for MoneySymbol { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x12type_options.proto\"-\n\x13RichTextDescription\x12\x16\n\x06format\ - \x18\x01\x20\x01(\tR\x06format\"6\n\x13CheckboxDescription\x12\x1f\n\x0b\ - is_selected\x18\x01\x20\x01(\x08R\nisSelected\"m\n\x0fDateDescription\ - \x12,\n\x0bdate_format\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\ - \x12,\n\x0btime_format\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat\ - \"g\n\x17SingleSelectDescription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\ - \r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\ - \x0cdisableColor\"f\n\x16MultiSelectDescription\x12'\n\x07options\x18\ - \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\ - \x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cSelectOption\x12\x0e\n\x02id\ - \x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\ - \x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05color\"\x9e\x01\n\x11NumberDe\ - scription\x12\"\n\x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05mon\ - ey\x12\x14\n\x05scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\ - \x18\x03\x20\x01(\tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\ - \x08R\x0csignPositive\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*6\n\ - \nDateFormat\x12\t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\ - \x03ISO\x10\x02\x12\x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\ - \nTwelveHour\x10\0\x12\x12\n\x0eTwentyFourHour\x10\x01*(\n\x0bMoneySymbo\ - l\x12\x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\ - \x02b\x06proto3\ -"; - -static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) -} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto new file mode 100644 index 0000000000..7c14ebc075 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message CheckboxDescription { + bool is_selected = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto new file mode 100644 index 0000000000..9fe4c4acfd --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +message DateDescription { + DateFormat date_format = 1; + TimeFormat time_format = 2; +} +enum DateFormat { + Local = 0; + US = 1; + ISO = 2; + Friendly = 3; +} +enum TimeFormat { + TwelveHour = 0; + TwentyFourHour = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto new file mode 100644 index 0000000000..83ab8b7220 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +message NumberDescription { + MoneySymbol money = 1; + uint32 scale = 2; + string symbol = 3; + bool sign_positive = 4; + string name = 5; +} +enum MoneySymbol { + CNY = 0; + EUR = 1; + USD = 2; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto new file mode 100644 index 0000000000..7f3ee25661 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +message SingleSelectDescription { + repeated SelectOption options = 1; + bool disable_color = 2; +} +message MultiSelectDescription { + repeated SelectOption options = 1; + bool disable_color = 2; +} +message SelectOption { + string id = 1; + string name = 2; + string color = 3; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto new file mode 100644 index 0000000000..c4ee8f8de6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message RichTextDescription { + string format = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto deleted file mode 100644 index 170035085c..0000000000 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto +++ /dev/null @@ -1,47 +0,0 @@ -syntax = "proto3"; - -message RichTextDescription { - string format = 1; -} -message CheckboxDescription { - bool is_selected = 1; -} -message DateDescription { - DateFormat date_format = 1; - TimeFormat time_format = 2; -} -message SingleSelectDescription { - repeated SelectOption options = 1; - bool disable_color = 2; -} -message MultiSelectDescription { - repeated SelectOption options = 1; - bool disable_color = 2; -} -message SelectOption { - string id = 1; - string name = 2; - string color = 3; -} -message NumberDescription { - MoneySymbol money = 1; - uint32 scale = 2; - string symbol = 3; - bool sign_positive = 4; - string name = 5; -} -enum DateFormat { - Local = 0; - US = 1; - ISO = 2; - Friendly = 3; -} -enum TimeFormat { - TwelveHour = 0; - TwentyFourHour = 1; -} -enum MoneySymbol { - CNY = 0; - EUR = 1; - USD = 2; -} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs new file mode 100644 index 0000000000..a472dec8c5 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs @@ -0,0 +1,137 @@ +use crate::services::cell::*; +use crate::services::field::TypeOptionsBuilder; +use flowy_grid_data_model::entities::FieldType; + +// Text +#[derive(Default)] +pub struct RichTextTypeOptionsBuilder(RichTextDescription); + +impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Number +#[derive(Default)] +pub struct NumberTypeOptionsBuilder(NumberDescription); + +impl NumberTypeOptionsBuilder { + pub fn name(mut self, name: &str) -> Self { + self.0.name = name.to_string(); + self + } + + pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { + self.0.set_money_symbol(money_symbol); + self + } + + pub fn scale(mut self, scale: u32) -> Self { + self.0.scale = scale; + self + } + + pub fn positive(mut self, positive: bool) -> Self { + self.0.sign_positive = positive; + self + } +} + +impl TypeOptionsBuilder for NumberTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Date +#[derive(Default)] +pub struct DateTypeOptionsBuilder(DateDescription); +impl DateTypeOptionsBuilder { + pub fn date_format(mut self, date_format: DateFormat) -> Self { + self.0.date_format = date_format; + self + } + + pub fn time_format(mut self, time_format: TimeFormat) -> Self { + self.0.time_format = time_format; + self + } +} +impl TypeOptionsBuilder for DateTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Single Select +#[derive(Default)] +pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); + +impl SingleSelectTypeOptionsBuilder { + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} +impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Multi Select +#[derive(Default)] +pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); + +impl MultiSelectTypeOptionsBuilder { + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} + +impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Checkbox +#[derive(Default)] +pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); +impl CheckboxTypeOptionsBuilder { + pub fn set_selected(mut self, is_selected: bool) -> Self { + self.0.is_selected = is_selected; + self + } +} +impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs new file mode 100644 index 0000000000..f6f3603604 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs @@ -0,0 +1,40 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +pub struct CheckboxDescription { + #[pb(index = 1)] + pub is_selected: bool, +} +impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); + +impl StringifyCellData for CheckboxDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + let s = match string_to_bool(s) { + true => "1", + false => "0", + }; + Ok(s.to_owned()) + } +} + +fn string_to_bool(bool_str: &str) -> bool { + let lower_case_str: &str = &bool_str.to_lowercase(); + match lower_case_str { + "1" => true, + "true" => true, + "yes" => true, + "0" => false, + "false" => false, + "no" => false, + _ => false, + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs new file mode 100644 index 0000000000..09cb04f163 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -0,0 +1,145 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use chrono::format::strftime::StrftimeItems; +use chrono::NaiveDateTime; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +// Date +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct DateDescription { + #[pb(index = 1)] + pub date_format: DateFormat, + + #[pb(index = 2)] + pub time_format: TimeFormat, +} +impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); + +impl DateDescription { + fn date_time_format_str(&self) -> String { + format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) + } + + #[allow(dead_code)] + fn today_from_timestamp(&self, timestamp: i64) -> String { + let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } + + fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String { + let utc: chrono::DateTime = chrono::DateTime::from_utc(naive, chrono::Utc); + let local: chrono::DateTime = chrono::DateTime::from(utc); + + let fmt_str = self.date_time_format_str(); + let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); + output + } +} + +impl StringifyCellData for DateDescription { + fn str_from_cell_data(&self, data: String) -> String { + match data.parse::() { + Ok(timestamp) => { + let native = NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } + Err(e) => { + tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); + String::new() + } + } + } + + fn str_to_cell_data(&self, s: &str) -> Result { + let timestamp = s + .parse::() + .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; + Ok(format!("{}", timestamp)) + } +} + +#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum DateFormat { + Local = 0, + US = 1, + ISO = 2, + Friendly = 3, +} +impl std::default::Default for DateFormat { + fn default() -> Self { + DateFormat::Friendly + } +} + +impl std::convert::From for DateFormat { + fn from(value: i32) -> Self { + match value { + 0 => DateFormat::Local, + 1 => DateFormat::US, + 2 => DateFormat::ISO, + 3 => DateFormat::Friendly, + _ => { + tracing::error!("Unsupported date format, fallback to friendly"); + DateFormat::Friendly + } + } + } +} + +impl DateFormat { + pub fn value(&self) -> i32 { + *self as i32 + } + // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html + pub fn format_str(&self) -> &'static str { + match self { + DateFormat::Local => "%Y/%m/%d", + DateFormat::US => "%Y/%m/%d", + DateFormat::ISO => "%Y-%m-%d", + DateFormat::Friendly => "%b %d,%Y", + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum TimeFormat { + TwelveHour = 0, + TwentyFourHour = 1, +} + +impl std::convert::From for TimeFormat { + fn from(value: i32) -> Self { + match value { + 0 => TimeFormat::TwelveHour, + 1 => TimeFormat::TwentyFourHour, + _ => { + tracing::error!("Unsupported time format, fallback to TwentyFourHour"); + TimeFormat::TwentyFourHour + } + } + } +} + +impl TimeFormat { + pub fn value(&self) -> i32 { + *self as i32 + } + + // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html + pub fn format_str(&self) -> &'static str { + match self { + TimeFormat::TwelveHour => "%r", + TimeFormat::TwentyFourHour => "%R", + } + } +} + +impl std::default::Default for TimeFormat { + fn default() -> Self { + TimeFormat::TwentyFourHour + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs new file mode 100644 index 0000000000..faadd45f8c --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs @@ -0,0 +1,11 @@ +mod checkbox_description; +mod date_description; +mod number_description; +mod selection_description; +mod text_description; + +pub use checkbox_description::*; +pub use date_description::*; +pub use number_description::*; +pub use selection_description::*; +pub use text_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs new file mode 100644 index 0000000000..569d3c8c95 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -0,0 +1,150 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use chrono::format::strftime::StrftimeItems; +use chrono::NaiveDateTime; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use rust_decimal::Decimal; +use rusty_money::{ + iso::{Currency, CNY, EUR, USD}, + Money, +}; +use serde::{Deserialize, Serialize}; +use std::str::FromStr; +use strum_macros::EnumIter; + +// Number +#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] +pub struct NumberDescription { + #[pb(index = 1)] + pub money: MoneySymbol, + + #[pb(index = 2)] + pub scale: u32, + + #[pb(index = 3)] + pub symbol: String, + + #[pb(index = 4)] + pub sign_positive: bool, + + #[pb(index = 5)] + pub name: String, +} +impl_from_and_to_type_option!(NumberDescription, FieldType::Number); + +impl std::default::Default for NumberDescription { + fn default() -> Self { + let money = MoneySymbol::default(); + let symbol = money.symbol_str(); + NumberDescription { + money, + scale: 0, + symbol, + sign_positive: true, + name: "Number".to_string(), + } + } +} + +impl NumberDescription { + pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { + self.money = money_symbol; + self.symbol = money_symbol.symbol_str(); + } + + fn money_from_str(&self, s: &str) -> Option { + match Decimal::from_str(s) { + Ok(mut decimal) => { + match decimal.set_scale(self.scale) { + Ok(_) => {} + Err(e) => { + tracing::error!("Set decimal scale failed: {:?}", e); + } + } + decimal.set_sign_positive(self.sign_positive); + Some(self.money.with_decimal(decimal).to_string()) + } + Err(e) => { + tracing::error!("Parser money from {} failed: {:?}", s, e); + None + } + } + } +} + +impl StringifyCellData for NumberDescription { + fn str_from_cell_data(&self, data: String) -> String { + match self.money_from_str(&data) { + Some(money_str) => money_str, + None => String::default(), + } + } + + fn str_to_cell_data(&self, s: &str) -> Result { + let strip_symbol_money = strip_money_symbol(s); + let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; + Ok(decimal.to_string()) + } +} + +#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum MoneySymbol { + CNY = 0, + EUR = 1, + USD = 2, +} + +impl std::default::Default for MoneySymbol { + fn default() -> Self { + MoneySymbol::USD + } +} + +impl MoneySymbol { + // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html + pub fn from_symbol_str(s: &str) -> MoneySymbol { + match s { + "CNY" => MoneySymbol::CNY, + "EUR" => MoneySymbol::EUR, + "USD" => MoneySymbol::USD, + _ => MoneySymbol::CNY, + } + } + + pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { + MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) + } + + pub fn currency(&self) -> &'static Currency { + match self { + MoneySymbol::CNY => CNY, + MoneySymbol::EUR => EUR, + MoneySymbol::USD => USD, + } + } + + // string_to_money("¥18,443").unwrap(); + // string_to_money("$18,443").unwrap(); + // string_to_money("€18,443").unwrap(); + pub fn code(&self) -> String { + self.currency().iso_alpha_code.to_string() + } + + pub fn symbol_str(&self) -> String { + self.currency().symbol.to_string() + } + + pub fn zero(&self) -> Money { + let mut decimal = Decimal::new(0, 0); + decimal.set_sign_positive(true); + self.with_decimal(decimal) + } + + pub fn with_decimal(&self, decimal: Decimal) -> Money { + let money = rusty_money::Money::from_decimal(decimal, self.currency()); + money + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs new file mode 100644 index 0000000000..872210b4b3 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -0,0 +1,70 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +// Single select +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct SingleSelectDescription { + #[pb(index = 1)] + pub options: Vec, + + #[pb(index = 2)] + pub disable_color: bool, +} +impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); + +impl StringifyCellData for SingleSelectDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) + } +} + +// Multiple select +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct MultiSelectDescription { + #[pb(index = 1)] + pub options: Vec, + + #[pb(index = 2)] + pub disable_color: bool, +} +impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); +impl StringifyCellData for MultiSelectDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) + } +} + +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct SelectOption { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub color: String, +} + +impl SelectOption { + pub fn new(name: &str) -> Self { + SelectOption { + id: uuid(), + name: name.to_owned(), + color: "".to_string(), + } + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs new file mode 100644 index 0000000000..228eed240d --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -0,0 +1,24 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct RichTextDescription { + #[pb(index = 1)] + pub format: String, +} +impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); + +impl StringifyCellData for RichTextDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs new file mode 100644 index 0000000000..0c28db7789 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs @@ -0,0 +1,5 @@ +mod builder; +mod description; + +pub use builder::*; +pub use description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 8b75389ce4..034e7c34fb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,7 +1,3 @@ -use crate::services::field::{ - CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, - RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, -}; use flowy_grid_data_model::entities::{Field, FieldType}; pub struct FieldBuilder { @@ -61,157 +57,3 @@ pub trait TypeOptionsBuilder { fn field_type(&self) -> FieldType; fn build(&self) -> String; } - -// Text -pub struct RichTextTypeOptionsBuilder(RichTextDescription); - -impl RichTextTypeOptionsBuilder { - pub fn new() -> Self { - Self(RichTextDescription::default()) - } -} - -impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Number -pub struct NumberTypeOptionsBuilder(NumberDescription); - -impl NumberTypeOptionsBuilder { - pub fn new() -> Self { - Self(NumberDescription::default()) - } - - pub fn name(mut self, name: &str) -> Self { - self.0.name = name.to_string(); - self - } - - pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { - self.0.set_money_symbol(money_symbol); - self - } - - pub fn scale(mut self, scale: u32) -> Self { - self.0.scale = scale; - self - } - - pub fn positive(mut self, positive: bool) -> Self { - self.0.sign_positive = positive; - self - } -} - -impl TypeOptionsBuilder for NumberTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Date -pub struct DateTypeOptionsBuilder(DateDescription); -impl DateTypeOptionsBuilder { - pub fn new() -> Self { - Self(DateDescription::default()) - } - - pub fn date_format(mut self, date_format: DateFormat) -> Self { - self.0.date_format = date_format; - self - } - - pub fn time_format(mut self, time_format: TimeFormat) -> Self { - self.0.time_format = time_format; - self - } -} -impl TypeOptionsBuilder for DateTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Single Select -pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); - -impl SingleSelectTypeOptionsBuilder { - pub fn new() -> Self { - Self(SingleSelectDescription::default()) - } - - pub fn option(mut self, opt: SelectOption) -> Self { - self.0.options.push(opt); - self - } -} -impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Multi Select -pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); - -impl MultiSelectTypeOptionsBuilder { - pub fn new() -> Self { - Self(MultiSelectDescription::default()) - } - - pub fn option(mut self, opt: SelectOption) -> Self { - self.0.options.push(opt); - self - } -} - -impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Checkbox -pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); -impl CheckboxTypeOptionsBuilder { - pub fn new() -> Self { - Self(CheckboxDescription::default()) - } - - pub fn set_selected(mut self, is_selected: bool) -> Self { - self.0.is_selected = is_selected; - self - } -} -impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 61b5889e68..50d069cf9b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,5 +1,3 @@ mod field_builder; -mod type_options; pub use field_builder::*; -pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs deleted file mode 100644 index 080e3aaa60..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ /dev/null @@ -1,390 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] -use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; -use crate::services::util::*; - -use chrono::format::strftime::StrftimeItems; -use chrono::NaiveDateTime; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; -use rust_decimal::Decimal; -use rusty_money::{ - iso::{Currency, CNY, EUR, USD}, - Money, -}; -use serde::{Deserialize, Serialize}; -use std::str::FromStr; -use strum_macros::EnumIter; - -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct RichTextDescription { - #[pb(index = 1)] - pub format: String, -} -impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); - -impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) - } -} - -// Checkbox -#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] -pub struct CheckboxDescription { - #[pb(index = 1)] - pub is_selected: bool, -} -impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); - -impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - let s = match string_to_bool(s) { - true => "1", - false => "0", - }; - Ok(s.to_owned()) - } -} - -// Date -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct DateDescription { - #[pb(index = 1)] - pub date_format: DateFormat, - - #[pb(index = 2)] - pub time_format: TimeFormat, -} -impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); - -impl DateDescription { - fn date_time_format_str(&self) -> String { - format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) - } - - #[allow(dead_code)] - fn today_from_timestamp(&self, timestamp: i64) -> String { - let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - - fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String { - let utc: chrono::DateTime = chrono::DateTime::from_utc(naive, chrono::Utc); - let local: chrono::DateTime = chrono::DateTime::from(utc); - - let fmt_str = self.date_time_format_str(); - let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); - output - } -} - -impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: String) -> String { - match data.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); - String::new() - } - } - } - - fn str_to_cell_data(&self, s: &str) -> Result { - let timestamp = s - .parse::() - .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(format!("{}", timestamp)) - } -} - -#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum DateFormat { - Local = 0, - US = 1, - ISO = 2, - Friendly = 3, -} -impl std::default::Default for DateFormat { - fn default() -> Self { - DateFormat::Friendly - } -} - -impl std::convert::From for DateFormat { - fn from(value: i32) -> Self { - match value { - 0 => DateFormat::Local, - 1 => DateFormat::US, - 2 => DateFormat::ISO, - 3 => DateFormat::Friendly, - _ => { - tracing::error!("Unsupported date format, fallback to friendly"); - DateFormat::Friendly - } - } - } -} - -impl DateFormat { - pub fn value(&self) -> i32 { - *self as i32 - } - // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html - pub fn format_str(&self) -> &'static str { - match self { - DateFormat::Local => "%Y/%m/%d", - DateFormat::US => "%Y/%m/%d", - DateFormat::ISO => "%Y-%m-%d", - DateFormat::Friendly => "%b %d,%Y", - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum TimeFormat { - TwelveHour = 0, - TwentyFourHour = 1, -} - -impl std::convert::From for TimeFormat { - fn from(value: i32) -> Self { - match value { - 0 => TimeFormat::TwelveHour, - 1 => TimeFormat::TwentyFourHour, - _ => { - tracing::error!("Unsupported time format, fallback to TwentyFourHour"); - TimeFormat::TwentyFourHour - } - } - } -} - -impl TimeFormat { - pub fn value(&self) -> i32 { - *self as i32 - } - - // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html - pub fn format_str(&self) -> &'static str { - match self { - TimeFormat::TwelveHour => "%r", - TimeFormat::TwentyFourHour => "%R", - } - } -} - -impl std::default::Default for TimeFormat { - fn default() -> Self { - TimeFormat::TwentyFourHour - } -} - -// Single select -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct SingleSelectDescription { - #[pb(index = 1)] - pub options: Vec, - - #[pb(index = 2)] - pub disable_color: bool, -} -impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); - -impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) - } -} - -// Multiple select -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct MultiSelectDescription { - #[pb(index = 1)] - pub options: Vec, - - #[pb(index = 2)] - pub disable_color: bool, -} -impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); -impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) - } -} - -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct SelectOption { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub name: String, - - #[pb(index = 3)] - pub color: String, -} - -impl SelectOption { - pub fn new(name: &str) -> Self { - SelectOption { - id: uuid(), - name: name.to_owned(), - color: "".to_string(), - } - } -} - -// Number -#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] -pub struct NumberDescription { - #[pb(index = 1)] - pub money: MoneySymbol, - - #[pb(index = 2)] - pub scale: u32, - - #[pb(index = 3)] - pub symbol: String, - - #[pb(index = 4)] - pub sign_positive: bool, - - #[pb(index = 5)] - pub name: String, -} -impl_from_and_to_type_option!(NumberDescription, FieldType::Number); - -impl std::default::Default for NumberDescription { - fn default() -> Self { - let money = MoneySymbol::default(); - let symbol = money.symbol_str(); - NumberDescription { - money, - scale: 0, - symbol, - sign_positive: true, - name: "Number".to_string(), - } - } -} - -impl NumberDescription { - pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { - self.money = money_symbol; - self.symbol = money_symbol.symbol_str(); - } - - fn money_from_str(&self, s: &str) -> Option { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - decimal.set_sign_positive(self.sign_positive); - Some(self.money.with_decimal(decimal).to_string()) - } - Err(e) => { - tracing::error!("Parser money from {} failed: {:?}", s, e); - None - } - } - } -} - -impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: String) -> String { - match self.money_from_str(&data) { - Some(money_str) => money_str, - None => String::default(), - } - } - - fn str_to_cell_data(&self, s: &str) -> Result { - let strip_symbol_money = strip_money_symbol(s); - let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - Ok(decimal.to_string()) - } -} - -#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, -} - -impl std::default::Default for MoneySymbol { - fn default() -> Self { - MoneySymbol::USD - } -} - -impl MoneySymbol { - // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_symbol_str(s: &str) -> MoneySymbol { - match s { - "CNY" => MoneySymbol::CNY, - "EUR" => MoneySymbol::EUR, - "USD" => MoneySymbol::USD, - _ => MoneySymbol::CNY, - } - } - - pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { - MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) - } - - pub fn currency(&self) -> &'static Currency { - match self { - MoneySymbol::CNY => CNY, - MoneySymbol::EUR => EUR, - MoneySymbol::USD => USD, - } - } - - // string_to_money("¥18,443").unwrap(); - // string_to_money("$18,443").unwrap(); - // string_to_money("€18,443").unwrap(); - pub fn code(&self) -> String { - self.currency().iso_alpha_code.to_string() - } - - pub fn symbol_str(&self) -> String { - self.currency().symbol.to_string() - } - - pub fn zero(&self) -> Money { - let mut decimal = Decimal::new(0, 0); - decimal.set_sign_positive(true); - self.with_decimal(decimal) - } - - pub fn with_decimal(&self, decimal: Decimal) -> Money { - let money = rusty_money::Money::from_decimal(decimal, self.currency()); - money - } -} diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 63defcf76b..c31b1734b3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,17 +1,20 @@ use crate::manager::GridUser; -use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; - use crate::services::grid_meta_editor::GridBlockMetaEditorManager; +use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use bytes::Bytes; -use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, + CellMetaChangeset, Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, + RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; +use std::collections::HashMap; +use crate::services::row::{ + make_row_by_row_id, make_rows, row_meta_from_context, CreateRowContext, CreateRowContextBuilder, +}; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; @@ -73,44 +76,83 @@ impl ClientGridEditor { Ok(()) } - pub async fn update_block(&self, change: GridBlockChangeset) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.update_block(change)?)).await?; + pub async fn update_block(&self, changeset: GridBlockChangeset) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?; Ok(()) } pub async fn create_row(&self) -> FlowyResult<()> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; - let grid_block = match self.grid_meta_pad.read().await.get_blocks().last() { - None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => Ok(grid_block.clone()), - }?; - - let row_count = self.block_meta_manager.create_row(fields, &grid_block).await?; - let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); - let _ = self.update_block(change).await?; + let block_id = self.last_block_id().await?; + let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&fields).build()); + let row_count = self.block_meta_manager.create_row(row).await?; + let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); + let _ = self.update_block(changeset).await?; Ok(()) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult> { - let fields = self.grid_meta_pad.read().await.get_fields(None)?; - let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; - Ok(rows) - } + pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + let block_id = self.last_block_id().await?; + let mut rows_by_block_id: HashMap> = HashMap::new(); - pub async fn get_all_rows(&self) -> FlowyResult> { - let fields = self.grid_meta_pad.read().await.get_fields(None)?; - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); - self.block_meta_manager.get_all_rows(grid_blocks, fields).await - } - - pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { - let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; - for (block_id, row_count) in row_counts { - let _ = self - .update_block(GridBlockChangeset::from_row_count(&block_id, row_count)) - .await?; + for ctx in contexts { + let row_meta = row_meta_from_context(&block_id, ctx); + rows_by_block_id + .entry(block_id.clone()) + .or_insert(Vec::new()) + .push(row_meta); } + let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; + for changeset in changesets { + let _ = self.update_block(changeset).await?; + } + Ok(()) + } + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + self.block_meta_manager.update_row(changeset).await + } + + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + let row_changeset: RowMetaChangeset = changeset.into(); + self.update_row(row_changeset).await + } + + pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + let row_metas = self.get_row_metas(&row_orders).await?; + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + match row_orders { + None => Ok(make_rows(&fields, row_metas)), + Some(row_orders) => { + let mut row_map: HashMap = make_row_by_row_id(&fields, row_metas); + let rows = row_orders + .iter() + .flat_map(|row_order| row_map.remove(&row_order.row_id)) + .collect::>(); + Ok(rows) + } + } + } + + pub async fn get_row_metas(&self, row_orders: &Option) -> FlowyResult> { + match row_orders { + None => { + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + let row_metas = self.block_meta_manager.get_all_rows(grid_blocks).await?; + Ok(row_metas) + } + Some(row_orders) => { + let row_metas = self.block_meta_manager.get_rows(row_orders).await?; + Ok(row_metas) + } + } + } + + pub async fn delete_rows(&self, row_ids: Vec) -> FlowyResult<()> { + let changesets = self.block_meta_manager.delete_rows(row_ids).await?; + for changeset in changesets { + let _ = self.update_block(changeset).await?; + } Ok(()) } @@ -165,6 +207,13 @@ impl ClientGridEditor { .await?; Ok(()) } + + async fn last_block_id(&self) -> FlowyResult { + match self.grid_meta_pad.read().await.get_blocks().last() { + None => Err(FlowyError::internal().context("There is no grid block in this grid")), + Some(grid_block) => Ok(grid_block.id.clone()), + } + } } #[cfg(feature = "flowy_unit_test")] @@ -174,24 +223,6 @@ impl ClientGridEditor { } } -async fn load_all_fields( - grid_pad: &GridMetaPad, - kv_persistence: &Arc, -) -> FlowyResult> { - let field_ids = grid_pad - .fields() - .iter() - .map(|field| field.id.clone()) - .collect::>(); - - let fields = kv_persistence.batch_get::(field_ids)?; - let map = DashMap::new(); - for field in fields { - map.insert(field.id.clone(), field); - } - Ok(map) -} - pub struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridMetaPad; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 211af6d340..918d8e7559 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,5 +1,5 @@ use crate::manager::GridUser; -use crate::services::row::{make_row_by_row_id, make_row_ids_per_block, make_rows, RowBuilder}; +use crate::services::row::make_row_ids_per_block; use bytes::Bytes; use dashmap::DashMap; @@ -7,7 +7,9 @@ use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, GridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{ + GridBlock, GridBlockChangeset, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, +}; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, @@ -16,19 +18,30 @@ use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; + +use dashmap::mapref::one::Ref; use std::sync::Arc; use tokio::sync::RwLock; +type RowId = String; +type BlockId = String; + pub(crate) struct GridBlockMetaEditorManager { user: Arc, editor_map: DashMap>, + block_id_by_row_id: DashMap, } impl GridBlockMetaEditorManager { pub(crate) async fn new(user: &Arc, blocks: Vec) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); - let manager = Self { user, editor_map }; + let block_id_by_row_id = DashMap::new(); + let manager = Self { + user, + editor_map, + block_id_by_row_id, + }; Ok(manager) } @@ -44,40 +57,98 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn create_row(&self, fields: Vec, grid_block: &GridBlock) -> FlowyResult { - let row = RowBuilder::new(&fields, &grid_block.id).build(); - let editor = self.get_editor(&grid_block.id).await?; + pub(crate) async fn create_row(&self, row: RowMeta) -> FlowyResult { + self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); + let editor = self.get_editor(&row.block_id).await?; editor.create_row(row).await } - pub(crate) async fn delete_rows(&self, _row_orders: Option) -> FlowyResult> { - Ok(vec![("".to_owned(), 2)]) - } - - pub(crate) async fn get_all_rows(&self, grid_blocks: Vec, fields: Vec) -> FlowyResult> { - let mut rows = vec![]; - for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.id).await?; - let row_metas = editor.get_rows(None).await?; - rows.extend(make_rows(&fields, row_metas)); + pub(crate) async fn insert_row( + &self, + rows_by_block_id: HashMap>, + ) -> FlowyResult> { + let mut changesets = vec![]; + for (block_id, rows) in rows_by_block_id { + let editor = self.get_editor(&block_id).await?; + let mut row_count = 0; + for row in rows { + self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); + row_count = editor.create_row(row).await?; + } + changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); } - Ok(rows) + + Ok(changesets) } - pub(crate) async fn get_rows(&self, fields: Vec, row_orders: RepeatedRowOrder) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { + let row_orders = row_ids + .into_iter() + .flat_map(|row_id| match self.block_id_by_row_id.get(&row_id) { + None => None, + Some(block_id) => Some(RowOrder { + row_id, + block_id: block_id.clone(), + }), + }) + .collect::>(); + let mut changesets = vec![]; let row_ids_per_blocks = make_row_ids_per_block(&row_orders); - let mut row_map: HashMap = HashMap::new(); for row_ids_per_block in row_ids_per_blocks { let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; - row_map.extend(make_row_by_row_id(&fields, row_metas)); + let row_count = editor.delete_rows(row_ids_per_block.row_ids).await?; + + let changeset = GridBlockChangeset::from_row_count(&row_ids_per_block.block_id, row_count); + changesets.push(changeset); } - let rows = row_orders - .iter() - .flat_map(|row_order| row_map.remove(&row_order.row_id)) - .collect::>(); - Ok(rows) + Ok(changesets) + } + + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + match self.block_id_by_row_id.get(&changeset.row_id) { + None => { + let msg = format!( + "Update Row failed. Can't find the corresponding block with row_id: {}", + changeset.row_id + ); + Err(FlowyError::internal().context(msg)) + } + Some(block_id) => { + let editor = self.get_editor(&block_id).await?; + editor.update_row(changeset).await + } + } + } + + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult> { + let mut row_metas = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let new_row_metas = editor.get_rows(None).await?; + new_row_metas.iter().for_each(|row_meta| { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + }); + + row_metas.extend(new_row_metas); + } + Ok(row_metas) + } + + pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult> { + let row_ids_per_blocks = make_row_ids_per_block(row_orders); + let mut row_metas = vec![]; + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let new_row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + new_row_metas.iter().for_each(|row_meta| { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + }); + row_metas.extend(new_row_metas); + } + Ok(row_metas) } } @@ -148,9 +219,16 @@ impl ClientGridBlockMetaEditor { Ok(row_count) } - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { - let _ = self.modify(|pad| Ok(pad.delete_rows(&ids)?)).await?; - Ok(()) + pub async fn delete_rows(&self, ids: Vec) -> FlowyResult { + let mut row_count = 0; + let _ = self + .modify(|pad| { + let changeset = pad.delete_rows(&ids)?; + row_count = pad.number_of_rows(); + Ok(changeset) + }) + .await?; + Ok(row_count) } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 0a7918b5d6..03a4f45c69 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,5 +1,6 @@ mod util; +pub mod cell; pub mod field; pub mod grid_editor; pub mod grid_meta_editor; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs index cd68038b9c..3a49d5f7e2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs @@ -1,5 +1,4 @@ -use crate::services::field::*; - +use crate::services::cell::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index d88b580788..7414c3ba8b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,24 +1,60 @@ -use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta}; +use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta, DEFAULT_ROW_HEIGHT}; +use std::collections::HashMap; -pub struct RowBuilder<'a> { - fields: &'a Vec, - row: RowMeta, +pub struct CreateRowContextBuilder<'a> { + #[allow(dead_code)] + fields: &'a [Field], + ctx: CreateRowContext, } -impl<'a> RowBuilder<'a> { - pub fn new(fields: &'a Vec, block_id: &'a String) -> Self { - let row = RowMeta::new(block_id); - Self { fields, row } +impl<'a> CreateRowContextBuilder<'a> { + pub fn new(fields: &'a [Field]) -> Self { + let ctx = CreateRowContext { + row_id: uuid::Uuid::new_v4().to_string(), + cell_by_field_id: Default::default(), + height: DEFAULT_ROW_HEIGHT, + visibility: true, + }; + Self { fields, ctx } } #[allow(dead_code)] pub fn add_cell(mut self, field_id: &str, data: String) -> Self { let cell = CellMeta::new(field_id, data); - self.row.cell_by_field_id.insert(field_id.to_owned(), cell); + self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); self } - pub fn build(self) -> RowMeta { - self.row + #[allow(dead_code)] + pub fn height(mut self, height: i32) -> Self { + self.ctx.height = height; + self + } + + #[allow(dead_code)] + pub fn visibility(mut self, visibility: bool) -> Self { + self.ctx.visibility = visibility; + self + } + + pub fn build(self) -> CreateRowContext { + self.ctx } } + +pub fn row_meta_from_context(block_id: &str, ctx: CreateRowContext) -> RowMeta { + RowMeta { + id: ctx.row_id, + block_id: block_id.to_owned(), + cell_by_field_id: ctx.cell_by_field_id, + height: ctx.height, + visibility: ctx.visibility, + } +} + +pub struct CreateRowContext { + pub row_id: String, + pub cell_by_field_id: HashMap, + pub height: i32, + pub visibility: bool, +} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 705871ad93..a1d766b81a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,5 +1,5 @@ use crate::services::row::stringify_deserialize; -use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta}; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; @@ -8,7 +8,7 @@ pub(crate) struct RowIdsPerBlock { pub(crate) row_ids: Vec, } -pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec { +pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { let mut map: HashMap = HashMap::new(); row_orders.iter().for_each(|row_order| { let block_id = row_order.block_id.clone(); @@ -21,7 +21,7 @@ pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec>() } -pub(crate) fn make_rows(fields: &Vec, row_metas: Vec) -> Vec { +pub(crate) fn make_rows(fields: &[Field], row_metas: Vec) -> Vec { let field_map = fields .iter() .map(|field| (&field.id, field)) @@ -59,7 +59,7 @@ fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: C } } -pub(crate) fn make_row_by_row_id(fields: &Vec, row_metas: Vec) -> HashMap { +pub(crate) fn make_row_by_row_id(fields: &[Field], row_metas: Vec) -> HashMap { let field_map = fields .iter() .map(|field| (&field.id, field)) diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index a82e748a3e..1639b293a2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,4 +1,4 @@ -use crate::services::field::MoneySymbol; +use crate::services::cell::MoneySymbol; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; use lazy_static::lazy_static; @@ -99,31 +99,6 @@ fn crop_letters(s: &mut String, pos: usize) { } } -pub fn string_to_bool(bool_str: &str) -> bool { - let lower_case_str: &str = &bool_str.to_lowercase(); - match lower_case_str { - "1" => true, - "true" => true, - "yes" => true, - "0" => false, - "false" => false, - "no" => false, - _ => false, - } -} - pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() } - -pub fn check_type_id(data: &AnyData, field: &Field) -> Result<(), FlowyError> { - let field_type = FieldType::from_type_id(&data.type_id).map_err(|e| FlowyError::internal().context(e))?; - if field_type != field.field_type { - tracing::error!( - "expected field type: {:?} but receive {:?} ", - field_type, - field.field_type - ); - } - Ok(()) -} diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index ef6060837e..80f942751a 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,15 +1,16 @@ +use crate::services::cell::*; use crate::services::field::*; use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; use flowy_grid_data_model::entities::FieldType; pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { - let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) .field_type(FieldType::RichText) .build(); - let single_select = SingleSelectTypeOptionsBuilder::new() + let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 410e7638a5..598bc46eda 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,10 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; -use flowy_grid_data_model::entities::{FieldChangeset, GridBlock, GridBlockChangeset}; +use flowy_grid::services::row::CreateRowContextBuilder; +use flowy_grid_data_model::entities::{ + FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMetaChangeset, +}; #[tokio::test] async fn default_grid_test() { @@ -55,7 +58,7 @@ async fn grid_create_duplicate_field() { #[tokio::test] async fn grid_update_field_with_empty_change() { let single_select_field = create_single_select_field(); - let change = FieldChangeset { + let changeset = FieldChangeset { field_id: single_select_field.id.clone(), name: None, desc: None, @@ -70,7 +73,7 @@ async fn grid_update_field_with_empty_change() { CreateField { field: single_select_field.clone(), }, - UpdateField { change }, + UpdateField { changeset }, AssertFieldEqual { field_index: 2, field: single_select_field, @@ -87,7 +90,7 @@ async fn grid_update_field() { let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); single_select_type_options.options.push(SelectOption::new("Unknown")); - let change = FieldChangeset { + let changeset = FieldChangeset { field_id: single_select_field.id.clone(), name: None, desc: None, @@ -106,7 +109,7 @@ async fn grid_update_field() { CreateField { field: single_select_field.clone(), }, - UpdateField { change }, + UpdateField { changeset }, AssertFieldEqual { field_index: 2, field: cloned_field, @@ -145,7 +148,7 @@ async fn grid_create_block() { async fn grid_update_block() { let grid_block = GridBlock::new(); let mut cloned_grid_block = grid_block.clone(); - let change = GridBlockChangeset { + let changeset = GridBlockChangeset { block_id: grid_block.id.clone(), start_row_index: Some(2), row_count: Some(10), @@ -157,7 +160,7 @@ async fn grid_update_block() { let scripts = vec![ AssertBlockCount(1), CreateBlock { block: grid_block }, - UpdateBlock { change }, + UpdateBlock { changeset }, AssertBlockCount(2), AssertBlockEqual { block_index: 1, @@ -169,6 +172,96 @@ async fn grid_update_block() { #[tokio::test] async fn grid_create_row() { - let scripts = vec![AssertRowCount(3), CreateRow, CreateRow, AssertRowCount(5)]; + let scripts = vec![AssertRowCount(3), CreateEmptyRow, CreateEmptyRow, AssertRowCount(5)]; GridEditorTest::new().await.run_scripts(scripts).await; } + +#[tokio::test] +async fn grid_create_row2() { + let mut test = GridEditorTest::new().await; + let create_row_context = CreateRowContextBuilder::new(&test.fields).build(); + let scripts = vec![ + AssertRowCount(3), + CreateRow { + context: create_row_context, + }, + AssertRowCount(4), + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_row() { + let mut test = GridEditorTest::new().await; + let context = CreateRowContextBuilder::new(&test.fields).build(); + let changeset = RowMetaChangeset { + row_id: context.row_id.clone(), + height: None, + visibility: None, + cell_by_field_id: Default::default(), + }; + + let scripts = vec![ + AssertRowCount(3), + CreateRow { context }, + UpdateRow { + changeset: changeset.clone(), + }, + AssertRow { changeset }, + AssertRowCount(4), + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_delete_row() { + let mut test = GridEditorTest::new().await; + let context_1 = CreateRowContextBuilder::new(&test.fields).build(); + let context_2 = CreateRowContextBuilder::new(&test.fields).build(); + let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; + let scripts = vec![ + AssertRowCount(3), + CreateRow { context: context_1 }, + CreateRow { context: context_2 }, + AssertBlockCount(1), + AssertBlock { + block_index: 0, + row_count: 5, + start_row_index: 0, + }, + DeleteRow { row_ids }, + AssertBlock { + block_index: 0, + row_count: 3, + start_row_index: 0, + }, + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_cell() { + let mut test = GridEditorTest::new().await; + let mut builder = CreateRowContextBuilder::new(&test.fields); + for field in &test.fields { + match field.field_type { + FieldType::RichText => { + builder = builder.add_cell(&field.id, "hello world".to_owned()); + } + FieldType::Number => { + builder = builder.add_cell(&field.id, "123".to_owned()); + } + FieldType::DateTime => { + builder = builder.add_cell(&field.id, "March 8, 2022".to_owned()); + } + FieldType::SingleSelect => {} + FieldType::MultiSelect => {} + FieldType::Checkbox => { + builder = builder.add_cell(&field.id, "1".to_owned()); + } + } + } + let context = builder.build(); + let scripts = vec![AssertRowCount(3), CreateRow { context }]; + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 278981dab3..e8e6660355 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,11 @@ +use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; +use flowy_grid::services::row::CreateRowContext; +use flowy_grid_data_model::entities::{ + CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMeta, RowMetaChangeset, +}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; - use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; @@ -10,16 +13,52 @@ use std::time::Duration; use tokio::time::sleep; pub enum EditorScript { - CreateField { field: Field }, - UpdateField { change: FieldChangeset }, - DeleteField { field: Field }, + CreateField { + field: Field, + }, + UpdateField { + changeset: FieldChangeset, + }, + DeleteField { + field: Field, + }, AssertFieldCount(usize), - AssertFieldEqual { field_index: usize, field: Field }, - CreateBlock { block: GridBlock }, - UpdateBlock { change: GridBlockChangeset }, + AssertFieldEqual { + field_index: usize, + field: Field, + }, + CreateBlock { + block: GridBlock, + }, + UpdateBlock { + changeset: GridBlockChangeset, + }, AssertBlockCount(usize), - AssertBlockEqual { block_index: usize, block: GridBlock }, - CreateRow, + AssertBlock { + block_index: usize, + row_count: i32, + start_row_index: i32, + }, + AssertBlockEqual { + block_index: usize, + block: GridBlock, + }, + CreateEmptyRow, + CreateRow { + context: CreateRowContext, + }, + UpdateRow { + changeset: RowMetaChangeset, + }, + AssertRow { + changeset: RowMetaChangeset, + }, + DeleteRow { + row_ids: Vec, + }, + UpdateCell { + changeset: CellMetaChangeset, + }, AssertRowCount(usize), // AssertRowEqual{ row_index: usize, row: RowMeta}, AssertGridMetaPad, @@ -29,6 +68,9 @@ pub struct GridEditorTest { pub sdk: FlowySDKTest, pub grid_id: String, pub editor: Arc, + pub fields: Vec, + pub grid_blocks: Vec, + pub row_metas: Vec, } impl GridEditorTest { @@ -37,8 +79,19 @@ impl GridEditorTest { let _ = sdk.init_user().await; let test = ViewTest::new_grid_view(&sdk).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); + let fields = editor.get_fields(None).await.unwrap(); + let grid_blocks = editor.get_blocks().await.unwrap(); + let row_metas = editor.get_row_metas(&None).await.unwrap(); + let grid_id = test.view.id; - Self { sdk, grid_id, editor } + Self { + sdk, + grid_id, + editor, + fields, + grid_blocks, + row_metas, + } } pub async fn run_scripts(&mut self, scripts: Vec) { @@ -56,16 +109,20 @@ impl GridEditorTest { match script { EditorScript::CreateField { field } => { self.editor.create_field(field).await.unwrap(); + self.fields = self.editor.get_fields(None).await.unwrap(); } - EditorScript::UpdateField { change } => { + EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); + self.fields = self.editor.get_fields(None).await.unwrap(); } EditorScript::DeleteField { field } => { self.editor.delete_field(&field.id).await.unwrap(); + self.fields = self.editor.get_fields(None).await.unwrap(); } EditorScript::AssertFieldCount(count) => { assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); } + EditorScript::AssertFieldEqual { field_index, field } => { let repeated_fields = self.editor.get_fields(None).await.unwrap(); let compared_field = repeated_fields[field_index].clone(); @@ -73,23 +130,60 @@ impl GridEditorTest { } EditorScript::CreateBlock { block } => { self.editor.create_block(block).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); } - EditorScript::UpdateBlock { change } => { + EditorScript::UpdateBlock { changeset: change } => { self.editor.update_block(change).await.unwrap(); } EditorScript::AssertBlockCount(count) => { assert_eq!(self.editor.get_blocks().await.unwrap().len(), count); } + EditorScript::AssertBlock { + block_index, + row_count, + start_row_index, + } => { + assert_eq!(self.grid_blocks[block_index].row_count, row_count); + assert_eq!(self.grid_blocks[block_index].start_row_index, start_row_index); + } EditorScript::AssertBlockEqual { block_index, block } => { let blocks = self.editor.get_blocks().await.unwrap(); let compared_block = blocks[block_index].clone(); assert_eq!(compared_block, block); } - EditorScript::CreateRow => { + EditorScript::CreateEmptyRow => { self.editor.create_row().await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); + } + EditorScript::CreateRow { context } => { + self.editor.insert_rows(vec![context]).await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); + } + EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), + EditorScript::DeleteRow { row_ids } => { + self.editor.delete_rows(row_ids).await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); + } + EditorScript::AssertRow { changeset } => { + let row = self.row_metas.iter().find(|row| row.id == changeset.row_id).unwrap(); + + if let Some(visibility) = changeset.visibility { + assert_eq!(row.visibility, visibility); + } + + if let Some(height) = changeset.height { + assert_eq!(row.height, height); + } + } + EditorScript::UpdateCell { changeset } => { + self.editor.update_cell(changeset).await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_all_rows().await.unwrap().len(), count); + assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; @@ -102,7 +196,7 @@ impl GridEditorTest { } pub fn create_text_field() -> Field { - FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) .field_type(FieldType::RichText) @@ -110,7 +204,7 @@ pub fn create_text_field() -> Field { } pub fn create_single_select_field() -> Field { - let single_select = SingleSelectTypeOptionsBuilder::new() + let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index b34f55b39b..5fe63ca7d1 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -33,6 +33,7 @@ impl GridBuilder { pub fn add_empty_row(mut self) -> Self { let row = RowMeta::new(&self.grid_block.id); self.grid_block_meta.rows.push(row); + self.grid_block.row_count += 1; self } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 89d2145e17..d7c9f13928 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -82,41 +82,41 @@ impl GridMetaPad { } } - pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult> { - let field_id = change.field_id.clone(); + pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { + let field_id = changeset.field_id.clone(); self.modify_field(&field_id, |field| { let mut is_changed = None; - if let Some(name) = change.name { + if let Some(name) = changeset.name { field.name = name; is_changed = Some(()) } - if let Some(desc) = change.desc { + if let Some(desc) = changeset.desc { field.desc = desc; is_changed = Some(()) } - if let Some(field_type) = change.field_type { + if let Some(field_type) = changeset.field_type { field.field_type = field_type; is_changed = Some(()) } - if let Some(frozen) = change.frozen { + if let Some(frozen) = changeset.frozen { field.frozen = frozen; is_changed = Some(()) } - if let Some(visibility) = change.visibility { + if let Some(visibility) = changeset.visibility { field.visibility = visibility; is_changed = Some(()) } - if let Some(width) = change.width { + if let Some(width) = changeset.width { field.width = width; is_changed = Some(()) } - if let Some(type_options) = change.type_options { + if let Some(type_options) = changeset.type_options { field.type_options = type_options; is_changed = Some(()) } @@ -141,17 +141,17 @@ impl GridMetaPad { self.grid_meta.blocks.clone() } - pub fn update_block(&mut self, change: GridBlockChangeset) -> CollaborateResult> { - let block_id = change.block_id.clone(); + pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { + let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; - if let Some(row_count) = change.row_count { + if let Some(row_count) = changeset.row_count { block.row_count = row_count; is_changed = Some(()); } - if let Some(start_row_index) = change.start_row_index { + if let Some(start_row_index) = changeset.start_row_index { block.start_row_index = start_row_index; is_changed = Some(()); } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index dee0a2b21b..05de0efa05 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -297,3 +297,36 @@ impl CellMeta { } } } + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellMetaChangeset { + #[pb(index = 1)] + pub row_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3, one_of)] + pub data: Option, +} + +impl std::convert::From for RowMetaChangeset { + fn from(changeset: CellMetaChangeset) -> Self { + let mut cell_by_field_id = HashMap::with_capacity(1); + if let Some(data) = changeset.data { + let field_id = changeset.field_id; + let cell_meta = CellMeta { + field_id: field_id.clone(), + data, + }; + cell_by_field_id.insert(field_id, cell_meta); + } + + RowMetaChangeset { + row_id: changeset.row_id, + height: None, + visibility: None, + cell_by_field_id, + } + } +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index a9fccf6d54..c8146c452a 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -2956,6 +2956,289 @@ impl ::protobuf::reflect::ProtobufValue for CellMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct CellMetaChangeset { + // message fields + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_data: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellMetaChangeset { + fn default() -> &'a CellMetaChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CellMetaChangeset_oneof_one_of_data { + data(::std::string::String), +} + +impl CellMetaChangeset { + pub fn new() -> CellMetaChangeset { + ::std::default::Default::default() + } + + // string row_id = 1; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string data = 3; + + + pub fn get_data(&self) -> &str { + match self.one_of_data { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(ref v)) => v, + _ => "", + } + } + pub fn clear_data(&mut self) { + self.one_of_data = ::std::option::Option::None; + } + + pub fn has_data(&self) -> bool { + match self.one_of_data { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::string::String) { + self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(v)) + } + + // Mutable pointer to the field. + pub fn mut_data(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(_)) = self.one_of_data { + } else { + self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(::std::string::String::new())); + } + match self.one_of_data { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_data(&mut self) -> ::std::string::String { + if self.has_data() { + match self.one_of_data.take() { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for CellMetaChangeset { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.row_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_data { + match v { + &CellMetaChangeset_oneof_one_of_data::data(ref v) => { + my_size += ::protobuf::rt::string_size(3, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.row_id.is_empty() { + os.write_string(1, &self.row_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_data { + match v { + &CellMetaChangeset_oneof_one_of_data::data(ref v) => { + os.write_string(3, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CellMetaChangeset { + CellMetaChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellMetaChangeset| { &m.row_id }, + |m: &mut CellMetaChangeset| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellMetaChangeset| { &m.field_id }, + |m: &mut CellMetaChangeset| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "data", + CellMetaChangeset::has_data, + CellMetaChangeset::get_data, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellMetaChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellMetaChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellMetaChangeset::new) + } +} + +impl ::protobuf::Clear for CellMetaChangeset { + fn clear(&mut self) { + self.row_id.clear(); + self.field_id.clear(); + self.one_of_data = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellMetaChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3059,10 +3342,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x12\n\x04data\x18\x02\x20\x01(\tR\x04data*d\n\tFieldType\x12\x0c\n\x08R\ - ichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\ - \x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\ - \x0c\n\x08Checkbox\x10\x05b\x06proto3\ + \x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\ + \x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\ + \x02\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04\ + dataB\r\n\x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\ + \n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingle\ + Select\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\ + \x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 190c400f04..77185fff5d 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -58,6 +58,11 @@ message CellMeta { string field_id = 1; string data = 2; } +message CellMetaChangeset { + string row_id = 1; + string field_id = 2; + oneof one_of_data { string data = 3; }; +} enum FieldType { RichText = 0; Number = 1; From 46be04f94ea8de5a4748e5e13ea178e77b38bfed Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 14 Mar 2022 23:16:25 +0800 Subject: [PATCH 038/179] chore: config update cell --- .../flowy-grid/number_description.pb.dart | 16 +- .../flowy-grid/number_description.pbenum.dart | 20 +- .../flowy-grid/number_description.pbjson.dart | 21 +- .../src/protobuf/model/number_description.rs | 89 ++++--- .../protobuf/proto/number_description.proto | 11 +- ...id_meta_editor.rs => block_meta_editor.rs} | 8 +- .../src/services/cell/builder/mod.rs | 4 +- .../cell/description/checkbox_description.rs | 22 +- .../cell/description/date_description.rs | 119 ++++++++- .../cell/description/number_description.rs | 250 ++++++++++++------ .../cell/description/selection_description.rs | 33 ++- .../cell/description/text_description.rs | 4 +- .../flowy-grid/src/services/grid_editor.rs | 2 +- .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- .../flowy-grid/src/services/row/row_loader.rs | 2 +- .../rust-lib/flowy-grid/src/services/util.rs | 132 +++------ .../flowy-grid/tests/grid/grid_test.rs | 41 ++- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- 18 files changed, 486 insertions(+), 294 deletions(-) rename frontend/rust-lib/flowy-grid/src/services/{grid_meta_editor.rs => block_meta_editor.rs} (98%) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart index 395ac5c07f..19064fbfd1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart @@ -15,7 +15,7 @@ export 'number_description.pbenum.dart'; class NumberDescription extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format', $pb.PbFieldType.OE, defaultOrMaker: NumberFormat.Number, valueOf: NumberFormat.valueOf, enumValues: NumberFormat.values) ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') @@ -25,15 +25,15 @@ class NumberDescription extends $pb.GeneratedMessage { NumberDescription._() : super(); factory NumberDescription({ - MoneySymbol? money, + NumberFormat? format, $core.int? scale, $core.String? symbol, $core.bool? signPositive, $core.String? name, }) { final _result = create(); - if (money != null) { - _result.money = money; + if (format != null) { + _result.format = format; } if (scale != null) { _result.scale = scale; @@ -71,13 +71,13 @@ class NumberDescription extends $pb.GeneratedMessage { static NumberDescription? _defaultInstance; @$pb.TagNumber(1) - MoneySymbol get money => $_getN(0); + NumberFormat get format => $_getN(0); @$pb.TagNumber(1) - set money(MoneySymbol v) { setField(1, v); } + set format(NumberFormat v) { setField(1, v); } @$pb.TagNumber(1) - $core.bool hasMoney() => $_has(0); + $core.bool hasFormat() => $_has(0); @$pb.TagNumber(1) - void clearMoney() => clearField(1); + void clearFormat() => clearField(1); @$pb.TagNumber(2) $core.int get scale => $_getIZ(1); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart index daae771fce..f5c3d38628 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart @@ -9,20 +9,22 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -class MoneySymbol extends $pb.ProtobufEnum { - static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); - static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); +class NumberFormat extends $pb.ProtobufEnum { + static const NumberFormat Number = NumberFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const NumberFormat USD = NumberFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + static const NumberFormat CNY = NumberFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const NumberFormat EUR = NumberFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - static const $core.List values = [ + static const $core.List values = [ + Number, + USD, CNY, EUR, - USD, ]; - static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); - static MoneySymbol? valueOf($core.int value) => _byValue[value]; + static final $core.Map<$core.int, NumberFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static NumberFormat? valueOf($core.int value) => _byValue[value]; - const MoneySymbol._($core.int v, $core.String n) : super(v, n); + const NumberFormat._($core.int v, $core.String n) : super(v, n); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart index 4a0c8db75a..ff1b3dc40f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart @@ -8,23 +8,24 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use moneySymbolDescriptor instead') -const MoneySymbol$json = const { - '1': 'MoneySymbol', +@$core.Deprecated('Use numberFormatDescriptor instead') +const NumberFormat$json = const { + '1': 'NumberFormat', '2': const [ - const {'1': 'CNY', '2': 0}, - const {'1': 'EUR', '2': 1}, - const {'1': 'USD', '2': 2}, + const {'1': 'Number', '2': 0}, + const {'1': 'USD', '2': 1}, + const {'1': 'CNY', '2': 2}, + const {'1': 'EUR', '2': 3}, ], }; -/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); +/// Descriptor for `NumberFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List numberFormatDescriptor = $convert.base64Decode('CgxOdW1iZXJGb3JtYXQSCgoGTnVtYmVyEAASBwoDVVNEEAESBwoDQ05ZEAISBwoDRVVSEAM='); @$core.Deprecated('Use numberDescriptionDescriptor instead') const NumberDescription$json = const { '1': 'NumberDescription', '2': const [ - const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, + const {'1': 'format', '3': 1, '4': 1, '5': 14, '6': '.NumberFormat', '10': 'format'}, const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, @@ -33,4 +34,4 @@ const NumberDescription$json = const { }; /// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); +final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIlCgZmb3JtYXQYASABKA4yDS5OdW1iZXJGb3JtYXRSBmZvcm1hdBIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs index 17bdb557e6..2137ea2be1 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs @@ -26,7 +26,7 @@ #[derive(PartialEq,Clone,Default)] pub struct NumberDescription { // message fields - pub money: MoneySymbol, + pub format: NumberFormat, pub scale: u32, pub symbol: ::std::string::String, pub sign_positive: bool, @@ -47,19 +47,19 @@ impl NumberDescription { ::std::default::Default::default() } - // .MoneySymbol money = 1; + // .NumberFormat format = 1; - pub fn get_money(&self) -> MoneySymbol { - self.money + pub fn get_format(&self) -> NumberFormat { + self.format } - pub fn clear_money(&mut self) { - self.money = MoneySymbol::CNY; + pub fn clear_format(&mut self) { + self.format = NumberFormat::Number; } // Param is passed by value, moved - pub fn set_money(&mut self, v: MoneySymbol) { - self.money = v; + pub fn set_format(&mut self, v: NumberFormat) { + self.format = v; } // uint32 scale = 2; @@ -155,7 +155,7 @@ impl ::protobuf::Message for NumberDescription { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.money, 1, &mut self.unknown_fields)? + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.format, 1, &mut self.unknown_fields)? }, 2 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -189,8 +189,8 @@ impl ::protobuf::Message for NumberDescription { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if self.money != MoneySymbol::CNY { - my_size += ::protobuf::rt::enum_size(1, self.money); + if self.format != NumberFormat::Number { + my_size += ::protobuf::rt::enum_size(1, self.format); } if self.scale != 0 { my_size += ::protobuf::rt::value_size(2, self.scale, ::protobuf::wire_format::WireTypeVarint); @@ -210,8 +210,8 @@ impl ::protobuf::Message for NumberDescription { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.money != MoneySymbol::CNY { - os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; + if self.format != NumberFormat::Number { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.format))?; } if self.scale != 0 { os.write_uint32(2, self.scale)?; @@ -263,10 +263,10 @@ impl ::protobuf::Message for NumberDescription { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "money", - |m: &NumberDescription| { &m.money }, - |m: &mut NumberDescription| { &mut m.money }, + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "format", + |m: &NumberDescription| { &m.format }, + |m: &mut NumberDescription| { &mut m.format }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( "scale", @@ -304,7 +304,7 @@ impl ::protobuf::Message for NumberDescription { impl ::protobuf::Clear for NumberDescription { fn clear(&mut self) { - self.money = MoneySymbol::CNY; + self.format = NumberFormat::Number; self.scale = 0; self.symbol.clear(); self.sign_positive = false; @@ -326,31 +326,34 @@ impl ::protobuf::reflect::ProtobufValue for NumberDescription { } #[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, +pub enum NumberFormat { + Number = 0, + USD = 1, + CNY = 2, + EUR = 3, } -impl ::protobuf::ProtobufEnum for MoneySymbol { +impl ::protobuf::ProtobufEnum for NumberFormat { fn value(&self) -> i32 { *self as i32 } - fn from_i32(value: i32) -> ::std::option::Option { + fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(MoneySymbol::CNY), - 1 => ::std::option::Option::Some(MoneySymbol::EUR), - 2 => ::std::option::Option::Some(MoneySymbol::USD), + 0 => ::std::option::Option::Some(NumberFormat::Number), + 1 => ::std::option::Option::Some(NumberFormat::USD), + 2 => ::std::option::Option::Some(NumberFormat::CNY), + 3 => ::std::option::Option::Some(NumberFormat::EUR), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { - static values: &'static [MoneySymbol] = &[ - MoneySymbol::CNY, - MoneySymbol::EUR, - MoneySymbol::USD, + static values: &'static [NumberFormat] = &[ + NumberFormat::Number, + NumberFormat::USD, + NumberFormat::CNY, + NumberFormat::EUR, ]; values } @@ -358,34 +361,34 @@ impl ::protobuf::ProtobufEnum for MoneySymbol { fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) + ::protobuf::reflect::EnumDescriptor::new_pb_name::("NumberFormat", file_descriptor_proto()) }) } } -impl ::std::marker::Copy for MoneySymbol { +impl ::std::marker::Copy for NumberFormat { } -impl ::std::default::Default for MoneySymbol { +impl ::std::default::Default for NumberFormat { fn default() -> Self { - MoneySymbol::CNY + NumberFormat::Number } } -impl ::protobuf::reflect::ProtobufValue for MoneySymbol { +impl ::protobuf::reflect::ProtobufValue for NumberFormat { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x18number_description.proto\"\x9e\x01\n\x11NumberDescription\x12\"\n\ - \x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05money\x12\x14\n\x05s\ - cale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\t\ - R\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositive\ - \x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*(\n\x0bMoneySymbol\x12\ - \x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\x02b\ - \x06proto3\ + \n\x18number_description.proto\"\xa1\x01\n\x11NumberDescription\x12%\n\ + \x06format\x18\x01\x20\x01(\x0e2\r.NumberFormatR\x06format\x12\x14\n\x05\ + scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\ + \tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositiv\ + e\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*5\n\x0cNumberFormat\x12\ + \n\n\x06Number\x10\0\x12\x07\n\x03USD\x10\x01\x12\x07\n\x03CNY\x10\x02\ + \x12\x07\n\x03EUR\x10\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto index 83ab8b7220..760f6623c4 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto @@ -1,14 +1,15 @@ syntax = "proto3"; message NumberDescription { - MoneySymbol money = 1; + NumberFormat format = 1; uint32 scale = 2; string symbol = 3; bool sign_positive = 4; string name = 5; } -enum MoneySymbol { - CNY = 0; - EUR = 1; - USD = 2; +enum NumberFormat { + Number = 0; + USD = 1; + CNY = 2; + EUR = 3; } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs similarity index 98% rename from frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs rename to frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 918d8e7559..3ac75cd70a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -19,7 +19,6 @@ use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; -use dashmap::mapref::one::Ref; use std::sync::Arc; use tokio::sync::RwLock; @@ -84,12 +83,11 @@ impl GridBlockMetaEditorManager { pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { let row_orders = row_ids .into_iter() - .flat_map(|row_id| match self.block_id_by_row_id.get(&row_id) { - None => None, - Some(block_id) => Some(RowOrder { + .flat_map(|row_id| { + self.block_id_by_row_id.get(&row_id).map(|block_id| RowOrder { row_id, block_id: block_id.clone(), - }), + }) }) .collect::>(); let mut changesets = vec![]; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs index a472dec8c5..6812d2c39d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs @@ -26,8 +26,8 @@ impl NumberTypeOptionsBuilder { self } - pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { - self.0.set_money_symbol(money_symbol); + pub fn set_format(mut self, format: NumberFormat) -> Self { + self.0.set_format(format); self } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs index f6f3603604..97c322bb95 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs @@ -1,6 +1,6 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; @@ -38,3 +38,23 @@ fn string_to_bool(bool_str: &str) -> bool { _ => false, } } + +#[cfg(test)] +mod tests { + use crate::services::cell::CheckboxDescription; + use crate::services::row::StringifyCellData; + + #[test] + fn checkout_box_description_test() { + let description = CheckboxDescription::default(); + assert_eq!(description.str_to_cell_data("true").unwrap(), "1".to_owned()); + assert_eq!(description.str_to_cell_data("1").unwrap(), "1".to_owned()); + assert_eq!(description.str_to_cell_data("yes").unwrap(), "1".to_owned()); + + assert_eq!(description.str_to_cell_data("false").unwrap(), "0".to_owned()); + assert_eq!(description.str_to_cell_data("no").unwrap(), "0".to_owned()); + assert_eq!(description.str_to_cell_data("123").unwrap(), "0".to_owned()); + + assert_eq!(description.str_from_cell_data("1".to_owned()), "1".to_owned()); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 09cb04f163..991357f63a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -1,6 +1,6 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use crate::services::util::*; + use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; @@ -8,6 +8,8 @@ use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; + // Date #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct DateDescription { @@ -20,10 +22,6 @@ pub struct DateDescription { impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); impl DateDescription { - fn date_time_format_str(&self) -> String { - format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) - } - #[allow(dead_code)] fn today_from_timestamp(&self, timestamp: i64) -> String { let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); @@ -34,7 +32,7 @@ impl DateDescription { let utc: chrono::DateTime = chrono::DateTime::from_utc(naive, chrono::Utc); let local: chrono::DateTime = chrono::DateTime::from(utc); - let fmt_str = self.date_time_format_str(); + let fmt_str = format!("{} {}", self.date_format.format_str(), self.time_format.format_str()); let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); output } @@ -55,14 +53,18 @@ impl StringifyCellData for DateDescription { } fn str_to_cell_data(&self, s: &str) -> Result { - let timestamp = s - .parse::() - .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; + let timestamp = match s.parse::() { + Ok(timestamp) => timestamp, + Err(e) => { + tracing::error!("Parse {} to i64 failed: {}", s, e); + chrono::Utc::now().timestamp() + } + }; Ok(format!("{}", timestamp)) } } -#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] +#[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] pub enum DateFormat { Local = 0, US = 1, @@ -105,7 +107,7 @@ impl DateFormat { } } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] +#[derive(Clone, Copy, PartialEq, Eq, EnumIter, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] pub enum TimeFormat { TwelveHour = 0, TwentyFourHour = 1, @@ -143,3 +145,98 @@ impl std::default::Default for TimeFormat { TimeFormat::TwentyFourHour } } + +#[cfg(test)] +mod tests { + use crate::services::cell::{DateDescription, DateFormat, TimeFormat}; + use crate::services::row::StringifyCellData; + use strum::IntoEnumIterator; + + #[test] + fn date_description_date_format_test() { + let mut description = DateDescription::default(); + let _timestamp = 1647251762; + + for date_format in DateFormat::iter() { + description.date_format = date_format; + match date_format { + DateFormat::Friendly => { + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + DateFormat::US => { + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + DateFormat::ISO => { + assert_eq!( + "2022-03-14 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "2022-03-14 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + DateFormat::Local => { + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + } + } + } + + #[test] + fn date_description_time_format_test() { + let mut description = DateDescription::default(); + for time_format in TimeFormat::iter() { + description.time_format = time_format; + match time_format { + TimeFormat::TwentyFourHour => { + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + TimeFormat::TwelveHour => { + assert_eq!( + "Mar 14,2022 05:56:02 PM".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 05:56:02 PM".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + } + } + } + + #[test] + fn date_description_invalid_data_test() { + let description = DateDescription::default(); + description.str_to_cell_data("he").unwrap(); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs index 569d3c8c95..b8470280f0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -1,25 +1,62 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use crate::services::util::*; -use chrono::format::strftime::StrftimeItems; -use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; +use lazy_static::lazy_static; +use rust_decimal::prelude::Zero; use rust_decimal::Decimal; -use rusty_money::{ - iso::{Currency, CNY, EUR, USD}, - Money, -}; +use rusty_money::iso::{Currency, CNY, EUR, USD}; use serde::{Deserialize, Serialize}; + use std::str::FromStr; +use strum::IntoEnumIterator; use strum_macros::EnumIter; +lazy_static! { + static ref STRIP_SYMBOL: Vec = make_strip_symbol(); +} + +#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum NumberFormat { + Number = 0, + USD = 1, + CNY = 2, + EUR = 3, +} + +impl std::default::Default for NumberFormat { + fn default() -> Self { + NumberFormat::Number + } +} + +impl NumberFormat { + pub fn symbol(&self) -> String { + match self { + NumberFormat::Number => "".to_string(), + NumberFormat::USD => USD.symbol.to_string(), + NumberFormat::CNY => CNY.symbol.to_string(), + NumberFormat::EUR => EUR.symbol.to_string(), + } + } + + #[allow(dead_code)] + pub fn code(&self) -> String { + match self { + NumberFormat::Number => "".to_string(), + NumberFormat::USD => USD.iso_alpha_code.to_string(), + NumberFormat::CNY => CNY.iso_alpha_code.to_string(), + NumberFormat::EUR => EUR.iso_alpha_code.to_string(), + } + } +} + // Number #[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] pub struct NumberDescription { #[pb(index = 1)] - pub money: MoneySymbol, + pub format: NumberFormat, #[pb(index = 2)] pub scale: u32, @@ -37,10 +74,10 @@ impl_from_and_to_type_option!(NumberDescription, FieldType::Number); impl std::default::Default for NumberDescription { fn default() -> Self { - let money = MoneySymbol::default(); - let symbol = money.symbol_str(); + let format = NumberFormat::default(); + let symbol = format.symbol(); NumberDescription { - money, + format, scale: 0, symbol, sign_positive: true, @@ -50,101 +87,156 @@ impl std::default::Default for NumberDescription { } impl NumberDescription { - pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { - self.money = money_symbol; - self.symbol = money_symbol.symbol_str(); + pub fn set_format(&mut self, format: NumberFormat) { + self.format = format; + self.symbol = format.symbol(); } - fn money_from_str(&self, s: &str) -> Option { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - decimal.set_sign_positive(self.sign_positive); - Some(self.money.with_decimal(decimal).to_string()) - } + fn decimal_from_str(&self, s: &str) -> Decimal { + let mut decimal = Decimal::from_str(s).unwrap_or(Decimal::zero()); + match decimal.set_scale(self.scale) { + Ok(_) => {} Err(e) => { - tracing::error!("Parser money from {} failed: {:?}", s, e); - None + tracing::error!("Set decimal scale failed: {:?}", e); } } + decimal.set_sign_positive(self.sign_positive); + decimal + } + + fn money_from_str(&self, s: &str, currency: &'static Currency) -> String { + let decimal = self.decimal_from_str(s); + let money = rusty_money::Money::from_decimal(decimal, currency); + money.to_string() + } + + fn strip_symbol(&self, s: &str) -> String { + let mut s = String::from(s); + if !s.chars().all(char::is_numeric) { + s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); + } + s } } impl StringifyCellData for NumberDescription { fn str_from_cell_data(&self, data: String) -> String { - match self.money_from_str(&data) { - Some(money_str) => money_str, - None => String::default(), + match self.format { + NumberFormat::Number => data, + NumberFormat::USD => self.money_from_str(&data, USD), + NumberFormat::CNY => self.money_from_str(&data, CNY), + NumberFormat::EUR => self.money_from_str(&data, EUR), } } fn str_to_cell_data(&self, s: &str) -> Result { - let strip_symbol_money = strip_money_symbol(s); - let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - Ok(decimal.to_string()) + Ok(self.strip_symbol(s)) } } -#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, -} - -impl std::default::Default for MoneySymbol { - fn default() -> Self { - MoneySymbol::USD +fn make_strip_symbol() -> Vec { + let mut symbols = vec![",".to_owned(), ".".to_owned()]; + for format in NumberFormat::iter() { + symbols.push(format.symbol()); } + symbols } -impl MoneySymbol { - // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_symbol_str(s: &str) -> MoneySymbol { - match s { - "CNY" => MoneySymbol::CNY, - "EUR" => MoneySymbol::EUR, - "USD" => MoneySymbol::USD, - _ => MoneySymbol::CNY, +#[cfg(test)] +mod tests { + use crate::services::cell::{NumberDescription, NumberFormat}; + use crate::services::row::StringifyCellData; + use strum::IntoEnumIterator; + + #[test] + fn number_description_test() { + let mut description = NumberDescription::default(); + assert_eq!(description.str_to_cell_data("¥18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.str_to_cell_data("$18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.str_to_cell_data("€18.443").unwrap(), "18443".to_owned()); + + for format in NumberFormat::iter() { + description.format = format; + match format { + NumberFormat::Number => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + } + NumberFormat::USD => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "$18,443".to_owned()); + } + NumberFormat::CNY => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "¥18,443".to_owned()); + } + NumberFormat::EUR => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "€18.443".to_owned()); + } + } } } - pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { - MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) - } + #[test] + fn number_description_scale_test() { + let mut description = NumberDescription::default(); + description.scale = 1; - pub fn currency(&self) -> &'static Currency { - match self { - MoneySymbol::CNY => CNY, - MoneySymbol::EUR => EUR, - MoneySymbol::USD => USD, + for format in NumberFormat::iter() { + description.format = format; + match format { + NumberFormat::Number => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + } + NumberFormat::USD => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "$1,844.3".to_owned() + ); + } + NumberFormat::CNY => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "¥1,844.3".to_owned() + ); + } + NumberFormat::EUR => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "€1.844,3".to_owned() + ); + } + } } } - // string_to_money("¥18,443").unwrap(); - // string_to_money("$18,443").unwrap(); - // string_to_money("€18,443").unwrap(); - pub fn code(&self) -> String { - self.currency().iso_alpha_code.to_string() - } + #[test] + fn number_description_sign_test() { + let mut description = NumberDescription::default(); + description.sign_positive = false; - pub fn symbol_str(&self) -> String { - self.currency().symbol.to_string() - } - - pub fn zero(&self) -> Money { - let mut decimal = Decimal::new(0, 0); - decimal.set_sign_positive(true); - self.with_decimal(decimal) - } - - pub fn with_decimal(&self, decimal: Decimal) -> Money { - let money = rusty_money::Money::from_decimal(decimal, self.currency()); - money + for format in NumberFormat::iter() { + description.format = format; + match format { + NumberFormat::Number => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + } + NumberFormat::USD => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "-$18,443".to_owned() + ); + } + NumberFormat::CNY => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "-¥18,443".to_owned() + ); + } + NumberFormat::EUR => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "-€18.443".to_owned() + ); + } + } + } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 872210b4b3..3a1485f31e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -1,7 +1,7 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; use crate::services::util::*; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; @@ -23,7 +23,7 @@ impl StringifyCellData for SingleSelectDescription { } fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) + Ok(select_option_id_from_data(s.to_owned(), true)) } } @@ -43,10 +43,22 @@ impl StringifyCellData for MultiSelectDescription { } fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) + Ok(select_option_id_from_data(s.to_owned(), false)) } } +fn select_option_id_from_data(data: String, is_single_select: bool) -> String { + if !is_single_select { + return data; + } + let select_option_ids = data.split(',').collect::>(); + if select_option_ids.is_empty() { + return "".to_owned(); + } + + select_option_ids.split_first().unwrap().0.to_string() +} + #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SelectOption { #[pb(index = 1)] @@ -68,3 +80,18 @@ impl SelectOption { } } } + +#[cfg(test)] +mod tests { + use crate::services::cell::{MultiSelectDescription, SingleSelectDescription}; + use crate::services::row::StringifyCellData; + + #[test] + fn selection_description_test() { + let description = SingleSelectDescription::default(); + assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1".to_owned()); + + let description = MultiSelectDescription::default(); + assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs index 228eed240d..4c9786abb7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -1,7 +1,7 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use crate::services::util::*; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; + +use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index c31b1734b3..32bb2d790b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,5 +1,5 @@ use crate::manager::GridUser; -use crate::services::grid_meta_editor::GridBlockMetaEditorManager; +use crate::services::block_meta_editor::GridBlockMetaEditorManager; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use bytes::Bytes; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 03a4f45c69..f8b0422685 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,8 +1,8 @@ mod util; +pub mod block_meta_editor; pub mod cell; pub mod field; pub mod grid_editor; -pub mod grid_meta_editor; pub mod kv_persistence; pub mod row; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index a1d766b81a..6f7640fb1e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,5 +1,5 @@ use crate::services::row::stringify_deserialize; -use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta, RowOrder}; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index 1639b293a2..b5c838fa12 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,103 +1,35 @@ -use crate::services::cell::MoneySymbol; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; -use lazy_static::lazy_static; -use rust_decimal::Decimal; -use rusty_money::{iso::Currency, Money}; -use std::collections::HashMap; -use std::str::FromStr; -use strum::IntoEnumIterator; - -lazy_static! { - static ref CURRENCIES_BY_SYMBOL: HashMap = generate_currency_by_symbol(); -} - -#[allow(dead_code)] -fn generate_currency_by_symbol() -> HashMap { - let mut map: HashMap = HashMap::new(); - - for money in MoneySymbol::iter() { - map.insert(money.symbol_str(), money.currency()); - } - map -} - -#[allow(dead_code)] -pub fn string_to_money(money_str: &str) -> Option> { - let mut process_money_str = String::from(money_str); - let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); - - if process_money_str.is_empty() { - return None; - } - - return if process_money_str.chars().all(char::is_numeric) { - match Money::from_str(&process_money_str, default_currency) { - Ok(money) => Some(money), - Err(_) => None, - } - } else { - let symbol = process_money_str.chars().next().unwrap().to_string(); - let mut currency = default_currency; - - for key in CURRENCIES_BY_SYMBOL.keys() { - if symbol.eq(key) { - currency = CURRENCIES_BY_SYMBOL.get(key).unwrap(); - crop_letters(&mut process_money_str, 1); - } - } - - match Money::from_str(&process_money_str, currency) { - Ok(money) => Some(money), - Err(_) => None, - } - }; -} - -#[allow(dead_code)] -pub fn money_from_str(s: &str) -> Option { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(0) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set scale failed. {:?}", e); - } - } - decimal.set_sign_positive(true); - Some(MoneySymbol::USD.with_decimal(decimal).to_string()) - } - Err(e) => { - tracing::debug!("Format {} to money failed, {:?}", s, e); - None - } - } -} - -pub fn strip_money_symbol(money_str: &str) -> String { - let mut process_money_str = String::from(money_str); - - if !process_money_str.chars().all(char::is_numeric) { - let symbol = process_money_str.chars().next().unwrap().to_string(); - for key in CURRENCIES_BY_SYMBOL.keys() { - if symbol.eq(key) { - crop_letters(&mut process_money_str, 1); - } - } - } - process_money_str -} - -fn crop_letters(s: &mut String, pos: usize) { - match s.char_indices().nth(pos) { - Some((pos, _)) => { - s.drain(..pos); - } - None => { - s.clear(); - } - } -} +// +// #[allow(dead_code)] +// pub fn string_to_money(money_str: &str) -> Option> { +// let mut process_money_str = String::from(money_str); +// let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); +// +// if process_money_str.is_empty() { +// return None; +// } +// +// return if process_money_str.chars().all(char::is_numeric) { +// match Money::from_str(&process_money_str, default_currency) { +// Ok(money) => Some(money), +// Err(_) => None, +// } +// } else { +// let symbol = process_money_str.chars().next().unwrap().to_string(); +// let mut currency = default_currency; +// +// for key in CURRENCIES_BY_SYMBOL.keys() { +// if symbol.eq(key) { +// currency = CURRENCIES_BY_SYMBOL.get(key).unwrap(); +// crop_letters(&mut process_money_str, 1); +// } +// } +// +// match Money::from_str(&process_money_str, currency) { +// Ok(money) => Some(money), +// Err(_) => None, +// } +// }; +// } pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 598bc46eda..360407b3b8 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,10 +1,8 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; -use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; -use flowy_grid::services::row::CreateRowContextBuilder; -use flowy_grid_data_model::entities::{ - FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMetaChangeset, -}; +use flowy_grid::services::cell::*; +use flowy_grid::services::row::{CreateRowContextBuilder, StringifyCellData}; +use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; #[tokio::test] async fn default_grid_test() { @@ -249,19 +247,40 @@ async fn grid_update_cell() { builder = builder.add_cell(&field.id, "hello world".to_owned()); } FieldType::Number => { - builder = builder.add_cell(&field.id, "123".to_owned()); + let description = NumberDescription::from(field); + let data = description.str_to_cell_data("¥18,443").unwrap(); + builder = builder.add_cell(&field.id, data); } FieldType::DateTime => { - builder = builder.add_cell(&field.id, "March 8, 2022".to_owned()); + let description = DateDescription::from(field); + let data = description.str_to_cell_data("1647251762").unwrap(); + builder = builder.add_cell(&field.id, data); + } + FieldType::SingleSelect => { + let description = SingleSelectDescription::from(field); + let options = description.options.first().unwrap(); + let data = description.str_to_cell_data(&options.id).unwrap(); + builder = builder.add_cell(&field.id, data); + } + FieldType::MultiSelect => { + let description = MultiSelectDescription::from(field); + let options = description + .options + .iter() + .map(|option| option.id.clone()) + .collect::>() + .join(","); + let data = description.str_to_cell_data(&options).unwrap(); + builder = builder.add_cell(&field.id, data); } - FieldType::SingleSelect => {} - FieldType::MultiSelect => {} FieldType::Checkbox => { - builder = builder.add_cell(&field.id, "1".to_owned()); + let description = CheckboxDescription::from(field); + let data = description.str_to_cell_data("false").unwrap(); + builder = builder.add_cell(&field.id, data); } } } let context = builder.build(); - let scripts = vec![AssertRowCount(3), CreateRow { context }]; + let scripts = vec![AssertRowCount(3), CreateRow { context }, AssertGridMetaPad]; test.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index e8e6660355..f123ecc9ed 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,7 +3,7 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowContext; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMeta, RowMetaChangeset, + CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -104,7 +104,7 @@ impl GridEditorTest { let grid_manager = self.sdk.grid_manager.clone(); let pool = self.sdk.user_session.db_pool().unwrap(); let rev_manager = self.editor.rev_manager(); - let cache = rev_manager.revision_cache().await; + let _cache = rev_manager.revision_cache().await; match script { EditorScript::CreateField { field } => { From 50f32521c50d02b346a62fc8d7adee5d5e62c3d9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 15 Mar 2022 11:07:18 +0800 Subject: [PATCH 039/179] chore: rename trait --- .../lib/startup/home_deps_resolver.dart | 1 - .../grid/cell_bloc/checkbox_cell_bloc.dart | 1 - .../grid/cell_bloc/date_cell_bloc.dart | 1 - .../grid/cell_bloc/number_cell_bloc.dart | 1 - .../grid/cell_bloc/selection_cell_bloc.dart | 1 - .../grid/cell_bloc/text_cell_bloc.dart | 1 - .../application/grid/column_bloc.dart | 2 +- .../lib/workspace/application/grid/data.dart | 1 - .../application/grid/grid_service.dart | 1 - .../plugins/grid/src/grid_page.dart | 2 +- .../plugins/grid/src/layout/layout.dart | 2 +- .../src/widgets/content/checkbox_cell.dart | 1 - .../grid/src/widgets/content/date_cell.dart | 1 - .../grid/src/widgets/content/number_cell.dart | 1 - .../src/widgets/content/selection_cell.dart | 1 - .../grid/src/widgets/content/text_cell.dart | 1 - .../grid/src/widgets/header/header.dart | 2 +- .../grid/src/widgets/header/header_cell.dart | 2 +- .../flowy-folder-data-model/view.pb.dart | 72 +-- .../flowy-folder-data-model/view.pbjson.dart | 15 +- .../flowy-grid-data-model/grid.pb.dart | 174 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 26 + .../flowy-grid-data-model/meta.pb.dart | 73 +-- .../flowy-grid-data-model/meta.pbjson.dart | 24 +- .../flowy-block/tests/document/script.rs | 2 +- .../src/services/view/controller.rs | 1 - .../flowy-folder/tests/workspace/script.rs | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 11 +- frontend/rust-lib/flowy-grid/src/macros.rs | 6 +- .../src/services/block_meta_editor.rs | 42 +- .../cell/description/checkbox_description.rs | 28 +- .../cell/description/date_description.rs | 30 +- .../cell/description/number_description.rs | 62 +- .../cell/description/selection_description.rs | 26 +- .../cell/description/text_description.rs | 12 +- .../src/services/field/field_builder.rs | 28 +- .../flowy-grid/src/services/grid_editor.rs | 37 +- .../src/services/row/cell_data_serde.rs | 32 + .../src/services/row/cell_stringify.rs | 33 - .../flowy-grid/src/services/row/mod.rs | 4 +- .../src/services/row/row_builder.rs | 6 +- .../flowy-grid/src/services/row/row_loader.rs | 25 +- .../flowy-grid/tests/grid/grid_test.rs | 55 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 58 +- .../flowy-net/src/local_server/server.rs | 2 +- frontend/rust-lib/flowy-test/src/helper.rs | 16 +- .../src/client_grid/block_pad.rs | 41 +- .../src/client_grid/grid_builder.rs | 14 +- .../src/client_grid/grid_pad.rs | 39 +- .../src/entities/view.rs | 16 +- .../src/protobuf/model/view.rs | 198 +++--- .../src/protobuf/proto/view.proto | 11 +- .../src/entities/grid.rs | 80 ++- .../src/entities/meta.rs | 40 +- .../src/protobuf/model/grid.rs | 597 +++++++++++++++++- .../src/protobuf/model/meta.rs | 311 +++------ .../src/protobuf/proto/grid.proto | 13 + .../src/protobuf/proto/meta.proto | 7 +- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- 59 files changed, 1444 insertions(+), 852 deletions(-) create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 367390efa0..5b91d8a545 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -13,7 +13,6 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index a4ef372a8b..8f0de7fb32 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index f24a9ee769..c8b5e97f2d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index 4959b67902..b216550a81 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 615c56f01e..5e7a6e8e22 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 0aa6c8e1a9..cce4ff9224 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart index 6313920223..39badc922a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 96f89c9eb0..c32f87f1a2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,6 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:equatable/equatable.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridInfo { List rows; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index a3f7f68760..e519b0a90d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,7 +3,6 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridService { Future> openGrid({required String gridId}) async { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 46c14d9b8d..7435ea0e5f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; import 'package:styled_widget/styled_widget.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 14f4a672cf..3f076fc89f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'sizes.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index ffa94d428e..d3d2b57735 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index f36bdb386c..e1661fdffa 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 143f741b15..86b9863019 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 6dc2a1922a..047cff7475 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index eef2f79195..7661ddc22f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 6a2adc619e..83d24535f4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 6217c9c344..aacdcd251e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index b79716fd25..350b5eac85 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -275,8 +275,8 @@ class CreateViewPayload extends $pb.GeneratedMessage { ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) - ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') - ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; @@ -287,8 +287,8 @@ class CreateViewPayload extends $pb.GeneratedMessage { $core.String? desc, $core.String? thumbnail, ViewDataType? dataType, - $core.String? extData, $core.int? pluginType, + $core.String? data, }) { final _result = create(); if (belongToId != null) { @@ -306,12 +306,12 @@ class CreateViewPayload extends $pb.GeneratedMessage { if (dataType != null) { _result.dataType = dataType; } - if (extData != null) { - _result.extData = extData; - } if (pluginType != null) { _result.pluginType = pluginType; } + if (data != null) { + _result.data = data; + } return _result; } factory CreateViewPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -384,22 +384,22 @@ class CreateViewPayload extends $pb.GeneratedMessage { void clearDataType() => clearField(5); @$pb.TagNumber(6) - $core.String get extData => $_getSZ(5); + $core.int get pluginType => $_getIZ(5); @$pb.TagNumber(6) - set extData($core.String v) { $_setString(5, v); } + set pluginType($core.int v) { $_setSignedInt32(5, v); } @$pb.TagNumber(6) - $core.bool hasExtData() => $_has(5); + $core.bool hasPluginType() => $_has(5); @$pb.TagNumber(6) - void clearExtData() => clearField(6); + void clearPluginType() => clearField(6); @$pb.TagNumber(7) - $core.int get pluginType => $_getIZ(6); + $core.String get data => $_getSZ(6); @$pb.TagNumber(7) - set pluginType($core.int v) { $_setSignedInt32(6, v); } + set data($core.String v) { $_setString(6, v); } @$pb.TagNumber(7) - $core.bool hasPluginType() => $_has(6); + $core.bool hasData() => $_has(6); @$pb.TagNumber(7) - void clearPluginType() => clearField(7); + void clearData() => clearField(7); } class CreateViewParams extends $pb.GeneratedMessage { @@ -409,10 +409,9 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) - ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') - ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') - ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..a<$core.int>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') + ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -423,7 +422,6 @@ class CreateViewParams extends $pb.GeneratedMessage { $core.String? desc, $core.String? thumbnail, ViewDataType? dataType, - $core.String? extData, $core.String? viewId, $core.String? data, $core.int? pluginType, @@ -444,9 +442,6 @@ class CreateViewParams extends $pb.GeneratedMessage { if (dataType != null) { _result.dataType = dataType; } - if (extData != null) { - _result.extData = extData; - } if (viewId != null) { _result.viewId = viewId; } @@ -525,40 +520,31 @@ class CreateViewParams extends $pb.GeneratedMessage { void clearDataType() => clearField(5); @$pb.TagNumber(6) - $core.String get extData => $_getSZ(5); + $core.String get viewId => $_getSZ(5); @$pb.TagNumber(6) - set extData($core.String v) { $_setString(5, v); } + set viewId($core.String v) { $_setString(5, v); } @$pb.TagNumber(6) - $core.bool hasExtData() => $_has(5); + $core.bool hasViewId() => $_has(5); @$pb.TagNumber(6) - void clearExtData() => clearField(6); + void clearViewId() => clearField(6); @$pb.TagNumber(7) - $core.String get viewId => $_getSZ(6); + $core.String get data => $_getSZ(6); @$pb.TagNumber(7) - set viewId($core.String v) { $_setString(6, v); } + set data($core.String v) { $_setString(6, v); } @$pb.TagNumber(7) - $core.bool hasViewId() => $_has(6); + $core.bool hasData() => $_has(6); @$pb.TagNumber(7) - void clearViewId() => clearField(7); + void clearData() => clearField(7); @$pb.TagNumber(8) - $core.String get data => $_getSZ(7); + $core.int get pluginType => $_getIZ(7); @$pb.TagNumber(8) - set data($core.String v) { $_setString(7, v); } + set pluginType($core.int v) { $_setSignedInt32(7, v); } @$pb.TagNumber(8) - $core.bool hasData() => $_has(7); + $core.bool hasPluginType() => $_has(7); @$pb.TagNumber(8) - void clearData() => clearField(8); - - @$pb.TagNumber(9) - $core.int get pluginType => $_getIZ(8); - @$pb.TagNumber(9) - set pluginType($core.int v) { $_setSignedInt32(8, v); } - @$pb.TagNumber(9) - $core.bool hasPluginType() => $_has(8); - @$pb.TagNumber(9) - void clearPluginType() => clearField(9); + void clearPluginType() => clearField(8); } class ViewId extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index adb1721475..358cb41100 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -59,8 +59,8 @@ const CreateViewPayload$json = const { const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, - const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'}, - const {'1': 'plugin_type', '3': 7, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'plugin_type', '3': 6, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, ], '8': const [ const {'1': 'one_of_thumbnail'}, @@ -68,7 +68,7 @@ const CreateViewPayload$json = const { }; /// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIZCghleHRfZGF0YRgGIAEoCVIHZXh0RGF0YRIfCgtwbHVnaW5fdHlwZRgHIAEoBVIKcGx1Z2luVHlwZUISChBvbmVfb2ZfdGh1bWJuYWls'); +final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgJUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw='); @$core.Deprecated('Use createViewParamsDescriptor instead') const CreateViewParams$json = const { '1': 'CreateViewParams', @@ -78,15 +78,14 @@ const CreateViewParams$json = const { const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, - const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'}, - const {'1': 'view_id', '3': 7, '4': 1, '5': 9, '10': 'viewId'}, - const {'1': 'data', '3': 8, '4': 1, '5': 9, '10': 'data'}, - const {'1': 'plugin_type', '3': 9, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'view_id', '3': 6, '4': 1, '5': 9, '10': 'viewId'}, + const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'plugin_type', '3': 8, '4': 1, '5': 5, '10': 'pluginType'}, ], }; /// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIZCghleHRfZGF0YRgGIAEoCVIHZXh0RGF0YRIXCgd2aWV3X2lkGAcgASgJUgZ2aWV3SWQSEgoEZGF0YRgIIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgJIAEoBVIKcGx1Z2luVHlwZQ=='); +final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ=='); @$core.Deprecated('Use viewIdDescriptor instead') const ViewId$json = const { '1': 'ViewId', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 4122de9503..60a0502420 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -9,6 +9,8 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'meta.pbenum.dart' as $0; + class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') @@ -72,6 +74,137 @@ class Grid extends $pb.GeneratedMessage { $core.List get rowOrders => $_getList(2); } +class Field extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e<$0.FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + Field._() : super(); + factory Field({ + $core.String? id, + $core.String? name, + $core.String? desc, + $0.FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + return _result; + } + factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Field clone() => Field()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Field create() => Field._(); + Field createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Field? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get desc => $_getSZ(2); + @$pb.TagNumber(3) + set desc($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDesc() => $_has(2); + @$pb.TagNumber(3) + void clearDesc() => clearField(3); + + @$pb.TagNumber(4) + $0.FieldType get fieldType => $_getN(3); + @$pb.TagNumber(4) + set fieldType($0.FieldType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasFieldType() => $_has(3); + @$pb.TagNumber(4) + void clearFieldType() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get frozen => $_getBF(4); + @$pb.TagNumber(5) + set frozen($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrozen() => $_has(4); + @$pb.TagNumber(5) + void clearFrozen() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get visibility => $_getBF(5); + @$pb.TagNumber(6) + set visibility($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasVisibility() => $_has(5); + @$pb.TagNumber(6) + void clearVisibility() => clearField(6); + + @$pb.TagNumber(7) + $core.int get width => $_getIZ(6); + @$pb.TagNumber(7) + set width($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasWidth() => $_has(6); + @$pb.TagNumber(7) + void clearWidth() => clearField(7); +} + class FieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') @@ -119,6 +252,47 @@ class FieldOrder extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); } +class RepeatedField extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + RepeatedField._() : super(); + factory RepeatedField({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedField clone() => RepeatedField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedField create() => RepeatedField._(); + RepeatedField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedField? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class RepeatedFieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedFieldOrder', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 2c1a16296d..0dc1fd25f6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -20,6 +20,22 @@ const Grid$json = const { /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); +@$core.Deprecated('Use fieldDescriptor instead') +const Field$json = const { + '1': 'Field', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, + const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, + const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, + const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, + ], +}; + +/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aA=='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -30,6 +46,16 @@ const FieldOrder$json = const { /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); +@$core.Deprecated('Use repeatedFieldDescriptor instead') +const RepeatedField$json = const { + '1': 'RepeatedField', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use repeatedFieldOrderDescriptor instead') const RepeatedFieldOrder$json = const { '1': 'RepeatedFieldOrder', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 12dbec7975..49168b0274 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -16,7 +16,7 @@ export 'meta.pbenum.dart'; class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlock.create) ..hasRequiredFields = false ; @@ -24,7 +24,7 @@ class GridMeta extends $pb.GeneratedMessage { GridMeta._() : super(); factory GridMeta({ $core.String? gridId, - $core.Iterable? fields, + $core.Iterable? fields, $core.Iterable? blocks, }) { final _result = create(); @@ -70,7 +70,7 @@ class GridMeta extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.List get fields => $_getList(1); + $core.List get fields => $_getList(1); @$pb.TagNumber(3) $core.List get blocks => $_getList(2); @@ -206,8 +206,8 @@ class GridBlockMeta extends $pb.GeneratedMessage { $core.List get rows => $_getList(1); } -class Field extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) +class FieldMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') @@ -219,8 +219,8 @@ class Field extends $pb.GeneratedMessage { ..hasRequiredFields = false ; - Field._() : super(); - factory Field({ + FieldMeta._() : super(); + factory FieldMeta({ $core.String? id, $core.String? name, $core.String? desc, @@ -257,26 +257,26 @@ class Field extends $pb.GeneratedMessage { } return _result; } - factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory FieldMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - Field clone() => Field()..mergeFromMessage(this); + FieldMeta clone() => FieldMeta()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use + FieldMeta copyWith(void Function(FieldMeta) updates) => super.copyWith((message) => updates(message as FieldMeta)) as FieldMeta; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static Field create() => Field._(); - Field createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static FieldMeta create() => FieldMeta._(); + FieldMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Field? _defaultInstance; + static FieldMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldMeta? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -587,47 +587,6 @@ class FieldChangeset extends $pb.GeneratedMessage { void clearTypeOptions() => clearField(8); } -class RepeatedField extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) - ..hasRequiredFields = false - ; - - RepeatedField._() : super(); - factory RepeatedField({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedField clone() => RepeatedField()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedField create() => RepeatedField._(); - RepeatedField createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedField? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - class AnyData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 728367ea13..3921f443c4 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -28,13 +28,13 @@ const GridMeta$json = const { '1': 'GridMeta', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, + const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlock', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIiCgZibG9ja3MYAyADKAsyCi5HcmlkQmxvY2tSBmJsb2Nrcw=='); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSIgoGYmxvY2tzGAMgAygLMgouR3JpZEJsb2NrUgZibG9ja3M='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', @@ -58,9 +58,9 @@ const GridBlockMeta$json = const { /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); -@$core.Deprecated('Use fieldDescriptor instead') -const Field$json = const { - '1': 'Field', +@$core.Deprecated('Use fieldMetaDescriptor instead') +const FieldMeta$json = const { + '1': 'FieldMeta', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, @@ -73,8 +73,8 @@ const Field$json = const { ], }; -/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIhCgx0eXBlX29wdGlvbnMYCCABKAlSC3R5cGVPcHRpb25z'); +/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSIQoMdHlwZV9vcHRpb25zGAggASgJUgt0eXBlT3B0aW9ucw=='); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', @@ -101,16 +101,6 @@ const FieldChangeset$json = const { /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEiMKDHR5cGVfb3B0aW9ucxgIIAEoCUgGUgt0eXBlT3B0aW9uc0INCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIVChNvbmVfb2ZfdHlwZV9vcHRpb25z'); -@$core.Deprecated('Use repeatedFieldDescriptor instead') -const RepeatedField$json = const { - '1': 'RepeatedField', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/rust-lib/flowy-block/tests/document/script.rs b/frontend/rust-lib/flowy-block/tests/document/script.rs index af237de010..2ae6e14fc9 100644 --- a/frontend/rust-lib/flowy-block/tests/document/script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/script.rs @@ -26,7 +26,7 @@ impl TextBlockEditorTest { pub async fn new() -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new_grid_view(&sdk).await; + let test = ViewTest::new_text_block_view(&sdk).await; let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index 79ce91e3bb..2d943df032 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -171,7 +171,6 @@ impl ViewController { data_type: view.data_type, data: delta_str, view_id: uuid(), - ext_data: view.ext_data, plugin_type: view.plugin_type, }; diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 9c2c8ecbed..3cb65a414c 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -350,8 +350,8 @@ pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &st desc: desc.to_string(), thumbnail: None, data_type, - ext_data: "".to_string(), plugin_type: 0, + data: "".to_string(), }; let view = FolderEventBuilder::new(sdk.clone()) .event(CreateView) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 5aa786431b..5028a40407 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,7 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - Cell, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, + Cell, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -13,7 +13,7 @@ pub(crate) async fn get_grid_data_handler( ) -> DataResult { let grid_id: GridId = data.into_inner(); let editor = manager.open_grid(grid_id).await?; - let grid = editor.grid_data().await; + let grid = editor.grid_data().await?; data_result(grid) } @@ -35,7 +35,12 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_field: RepeatedField = editor.get_fields(Some(payload.field_orders)).await?.into(); + let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?; + let repeated_field: RepeatedField = field_metas + .into_iter() + .map(|field_meta| Field::from(field_meta)) + .collect::>() + .into(); data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index ce638f96b8..d7a5fc8bf8 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -9,9 +9,9 @@ macro_rules! impl_from_and_to_type_option { #[macro_export] macro_rules! impl_from_field_type_option { ($target: ident) => { - impl std::convert::From<&Field> for $target { - fn from(field: &Field) -> $target { - match serde_json::from_str(&field.type_options) { + impl std::convert::From<&FieldMeta> for $target { + fn from(field_meta: &FieldMeta) -> $target { + match serde_json::from_str(&field_meta.type_options) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 3ac75cd70a..c691e0b12c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -119,11 +119,11 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult> { + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult>> { let mut row_metas = vec![]; for grid_block in grid_blocks { let editor = self.get_editor(&grid_block.id).await?; - let new_row_metas = editor.get_rows(None).await?; + let new_row_metas = editor.get_row_metas(None).await?; new_row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); @@ -134,12 +134,23 @@ impl GridBlockMetaEditorManager { Ok(row_metas) } - pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult> { + pub(crate) async fn get_row_orders(&self, grid_blocks: Vec) -> FlowyResult> { + let mut row_orders = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let row_metas = editor.get_row_metas(None).await?; + let block_row_orders = row_metas.iter().map(|row_meta| RowOrder::from(row_meta)); + row_orders.extend(block_row_orders); + } + Ok(row_orders) + } + + pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult>> { let row_ids_per_blocks = make_row_ids_per_block(row_orders); let mut row_metas = vec![]; for row_ids_per_block in row_ids_per_blocks { let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let new_row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + let new_row_metas = editor.get_row_metas(Some(row_ids_per_block.row_ids)).await?; new_row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); @@ -234,14 +245,21 @@ impl ClientGridBlockMetaEditor { Ok(()) } - pub async fn get_rows(&self, row_ids: Option>) -> FlowyResult> { - match row_ids { - None => Ok(self.meta_pad.read().await.all_rows()), - Some(row_ids) => { - let rows = self.meta_pad.read().await.get_rows(row_ids)?; - Ok(rows) - } - } + pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { + let row_metas = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(row_metas) + } + + pub async fn get_row_orders(&self) -> FlowyResult> { + let row_orders = self + .meta_pad + .read() + .await + .get_rows(None)? + .iter() + .map(|row_meta| RowOrder::from(row_meta)) + .collect::>(); + Ok(row_orders) } async fn modify(&self, f: F) -> FlowyResult<()> diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs index 97c322bb95..87bd7f848c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs @@ -1,8 +1,8 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] @@ -12,13 +12,13 @@ pub struct CheckboxDescription { } impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); -impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for CheckboxDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - let s = match string_to_bool(s) { + fn serialize_cell_data(&self, data: &str) -> Result { + let s = match string_to_bool(data) { true => "1", false => "0", }; @@ -42,19 +42,19 @@ fn string_to_bool(bool_str: &str) -> bool { #[cfg(test)] mod tests { use crate::services::cell::CheckboxDescription; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; #[test] fn checkout_box_description_test() { let description = CheckboxDescription::default(); - assert_eq!(description.str_to_cell_data("true").unwrap(), "1".to_owned()); - assert_eq!(description.str_to_cell_data("1").unwrap(), "1".to_owned()); - assert_eq!(description.str_to_cell_data("yes").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("true").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("1").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("yes").unwrap(), "1".to_owned()); - assert_eq!(description.str_to_cell_data("false").unwrap(), "0".to_owned()); - assert_eq!(description.str_to_cell_data("no").unwrap(), "0".to_owned()); - assert_eq!(description.str_to_cell_data("123").unwrap(), "0".to_owned()); + assert_eq!(description.serialize_cell_data("false").unwrap(), "0".to_owned()); + assert_eq!(description.serialize_cell_data("no").unwrap(), "0".to_owned()); + assert_eq!(description.serialize_cell_data("123").unwrap(), "0".to_owned()); - assert_eq!(description.str_from_cell_data("1".to_owned()), "1".to_owned()); + assert_eq!(description.deserialize_cell_data("1".to_owned()), "1".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 991357f63a..1b057b5314 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -1,11 +1,11 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; use strum_macros::EnumIter; @@ -38,8 +38,8 @@ impl DateDescription { } } -impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for DateDescription { + fn deserialize_cell_data(&self, data: String) -> String { match data.parse::() { Ok(timestamp) => { let native = NaiveDateTime::from_timestamp(timestamp, 0); @@ -52,11 +52,11 @@ impl StringifyCellData for DateDescription { } } - fn str_to_cell_data(&self, s: &str) -> Result { - let timestamp = match s.parse::() { + fn serialize_cell_data(&self, data: &str) -> Result { + let timestamp = match data.parse::() { Ok(timestamp) => timestamp, Err(e) => { - tracing::error!("Parse {} to i64 failed: {}", s, e); + tracing::error!("Parse {} to i64 failed: {}", data, e); chrono::Utc::now().timestamp() } }; @@ -149,7 +149,7 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { use crate::services::cell::{DateDescription, DateFormat, TimeFormat}; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] @@ -167,7 +167,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } DateFormat::US => { @@ -177,7 +177,7 @@ mod tests { ); assert_eq!( "2022/03/14 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } DateFormat::ISO => { @@ -187,7 +187,7 @@ mod tests { ); assert_eq!( "2022-03-14 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } DateFormat::Local => { @@ -197,7 +197,7 @@ mod tests { ); assert_eq!( "2022/03/14 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } } @@ -217,7 +217,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } TimeFormat::TwelveHour => { @@ -227,7 +227,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 05:56:02 PM".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } } @@ -237,6 +237,6 @@ mod tests { #[test] fn date_description_invalid_data_test() { let description = DateDescription::default(); - description.str_to_cell_data("he").unwrap(); + description.serialize_cell_data("he").unwrap(); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs index b8470280f0..a4a3c08d90 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -1,8 +1,8 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use lazy_static::lazy_static; use rust_decimal::prelude::Zero; use rust_decimal::Decimal; @@ -119,8 +119,8 @@ impl NumberDescription { } } -impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for NumberDescription { + fn deserialize_cell_data(&self, data: String) -> String { match self.format { NumberFormat::Number => data, NumberFormat::USD => self.money_from_str(&data, USD), @@ -129,8 +129,8 @@ impl StringifyCellData for NumberDescription { } } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(self.strip_symbol(s)) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(self.strip_symbol(data)) } } @@ -145,30 +145,42 @@ fn make_strip_symbol() -> Vec { #[cfg(test)] mod tests { use crate::services::cell::{NumberDescription, NumberFormat}; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] fn number_description_test() { let mut description = NumberDescription::default(); - assert_eq!(description.str_to_cell_data("¥18,443").unwrap(), "18443".to_owned()); - assert_eq!(description.str_to_cell_data("$18,443").unwrap(), "18443".to_owned()); - assert_eq!(description.str_to_cell_data("€18.443").unwrap(), "18443".to_owned()); + assert_eq!(description.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.serialize_cell_data("$18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.serialize_cell_data("€18.443").unwrap(), "18443".to_owned()); for format in NumberFormat::iter() { description.format = format; match format { NumberFormat::Number => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "18443".to_owned() + ); } NumberFormat::USD => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "$18,443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "$18,443".to_owned() + ); } NumberFormat::CNY => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "¥18,443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "¥18,443".to_owned() + ); } NumberFormat::EUR => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "€18.443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "€18.443".to_owned() + ); } } } @@ -183,23 +195,26 @@ mod tests { description.format = format; match format { NumberFormat::Number => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "18443".to_owned() + ); } NumberFormat::USD => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "$1,844.3".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "¥1,844.3".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "€1.844,3".to_owned() ); } @@ -216,23 +231,26 @@ mod tests { description.format = format; match format { NumberFormat::Number => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "18443".to_owned() + ); } NumberFormat::USD => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "-$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "-¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "-€18.443".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 3a1485f31e..2f772c3c5d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -1,9 +1,9 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use crate::services::util::*; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; // Single select @@ -17,13 +17,13 @@ pub struct SingleSelectDescription { } impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); -impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for SingleSelectDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(select_option_id_from_data(s.to_owned(), true)) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(select_option_id_from_data(data.to_owned(), true)) } } @@ -37,13 +37,13 @@ pub struct MultiSelectDescription { pub disable_color: bool, } impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); -impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for MultiSelectDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(select_option_id_from_data(s.to_owned(), false)) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(select_option_id_from_data(data.to_owned(), false)) } } @@ -84,14 +84,14 @@ impl SelectOption { #[cfg(test)] mod tests { use crate::services::cell::{MultiSelectDescription, SingleSelectDescription}; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; #[test] fn selection_description_test() { let description = SingleSelectDescription::default(); - assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); let description = MultiSelectDescription::default(); - assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs index 4c9786abb7..1f71244519 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -1,9 +1,9 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] @@ -13,12 +13,12 @@ pub struct RichTextDescription { } impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); -impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for RichTextDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(data.to_owned()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 034e7c34fb..15f5b805d9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,55 +1,55 @@ -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; pub struct FieldBuilder { - field: Field, + field_meta: FieldMeta, type_options_builder: Box, } impl FieldBuilder { pub fn new(type_options_builder: T) -> Self { - let field = Field::new("Name", "", FieldType::RichText); + let field_meta = FieldMeta::new("Name", "", FieldType::RichText); Self { - field, + field_meta, type_options_builder: Box::new(type_options_builder), } } pub fn name(mut self, name: &str) -> Self { - self.field.name = name.to_owned(); + self.field_meta.name = name.to_owned(); self } pub fn desc(mut self, desc: &str) -> Self { - self.field.desc = desc.to_owned(); + self.field_meta.desc = desc.to_owned(); self } pub fn field_type(mut self, field_type: FieldType) -> Self { - self.field.field_type = field_type; + self.field_meta.field_type = field_type; self } pub fn visibility(mut self, visibility: bool) -> Self { - self.field.visibility = visibility; + self.field_meta.visibility = visibility; self } pub fn width(mut self, width: i32) -> Self { - self.field.width = width; + self.field_meta.width = width; self } pub fn frozen(mut self, frozen: bool) -> Self { - self.field.frozen = frozen; + self.field_meta.frozen = frozen; self } - pub fn build(mut self) -> Field { - assert_eq!(self.field.field_type, self.type_options_builder.field_type()); + pub fn build(mut self) -> FieldMeta { + assert_eq!(self.field_meta.field_type, self.type_options_builder.field_type()); let type_options = self.type_options_builder.build(); - self.field.type_options = type_options; - self.field + self.field_meta.type_options = type_options; + self.field_meta } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 32bb2d790b..e45dad5394 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -7,7 +7,7 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, + CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; @@ -56,8 +56,8 @@ impl ClientGridEditor { })) } - pub async fn create_field(&self, field: Field) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; + pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?; Ok(()) } @@ -82,9 +82,9 @@ impl ClientGridEditor { } pub async fn create_row(&self) -> FlowyResult<()> { - let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; - let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&fields).build()); + let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&field_metas).build()); let row_count = self.block_meta_manager.create_row(row).await?; let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; @@ -119,12 +119,12 @@ impl ClientGridEditor { } pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { - let row_metas = self.get_row_metas(&row_orders).await?; - let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let row_metas = self.get_row_metas(row_orders.as_ref()).await?; + let field_meta = self.grid_meta_pad.read().await.get_field_metas(None)?; match row_orders { - None => Ok(make_rows(&fields, row_metas)), + None => Ok(make_rows(&field_meta, row_metas)), Some(row_orders) => { - let mut row_map: HashMap = make_row_by_row_id(&fields, row_metas); + let mut row_map: HashMap = make_row_by_row_id(&field_meta, row_metas); let rows = row_orders .iter() .flat_map(|row_order| row_map.remove(&row_order.row_id)) @@ -134,7 +134,7 @@ impl ClientGridEditor { } } - pub async fn get_row_metas(&self, row_orders: &Option) -> FlowyResult> { + pub async fn get_row_metas(&self, row_orders: Option<&RepeatedRowOrder>) -> FlowyResult>> { match row_orders { None => { let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); @@ -156,13 +156,20 @@ impl ClientGridEditor { Ok(()) } - pub async fn grid_data(&self) -> Grid { - todo!() + pub async fn grid_data(&self) -> FlowyResult { + let field_orders = self.grid_meta_pad.read().await.get_field_orders(); + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + let row_orders = self.block_meta_manager.get_row_orders(grid_blocks).await?; + Ok(Grid { + id: self.grid_id.clone(), + field_orders, + row_orders, + }) } - pub async fn get_fields(&self, field_orders: Option) -> FlowyResult> { - let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; - Ok(fields) + pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { + let field_meta = self.grid_meta_pad.read().await.get_field_metas(field_orders)?; + Ok(field_meta) } pub async fn get_blocks(&self) -> FlowyResult> { diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs new file mode 100644 index 0000000000..148b5254ba --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs @@ -0,0 +1,32 @@ +use crate::services::cell::*; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; + +pub trait CellDataSerde { + fn deserialize_cell_data(&self, data: String) -> String; + fn serialize_cell_data(&self, data: &str) -> Result; +} + +#[allow(dead_code)] +pub fn serialize_cell_data(data: &str, field: &FieldMeta) -> Result { + match field.field_type { + FieldType::RichText => RichTextDescription::from(field).serialize_cell_data(data), + FieldType::Number => NumberDescription::from(field).serialize_cell_data(data), + FieldType::DateTime => DateDescription::from(field).serialize_cell_data(data), + FieldType::SingleSelect => SingleSelectDescription::from(field).serialize_cell_data(data), + FieldType::MultiSelect => MultiSelectDescription::from(field).serialize_cell_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).serialize_cell_data(data), + } +} + +pub fn deserialize_cell_data(data: String, field: &FieldMeta) -> Result { + let s = match field.field_type { + FieldType::RichText => RichTextDescription::from(field).deserialize_cell_data(data), + FieldType::Number => NumberDescription::from(field).deserialize_cell_data(data), + FieldType::DateTime => DateDescription::from(field).deserialize_cell_data(data), + FieldType::SingleSelect => SingleSelectDescription::from(field).deserialize_cell_data(data), + FieldType::MultiSelect => MultiSelectDescription::from(field).deserialize_cell_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).deserialize_cell_data(data), + }; + Ok(s) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs deleted file mode 100644 index 3a49d5f7e2..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::services::cell::*; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; - -pub trait StringifyCellData { - fn str_from_cell_data(&self, data: String) -> String; - fn str_to_cell_data(&self, s: &str) -> Result; -} - -#[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { - match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), - FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), - FieldType::DateTime => DateDescription::from(field).str_to_cell_data(s), - FieldType::SingleSelect => SingleSelectDescription::from(field).str_to_cell_data(s), - FieldType::MultiSelect => MultiSelectDescription::from(field).str_to_cell_data(s), - FieldType::Checkbox => CheckboxDescription::from(field).str_to_cell_data(s), - } -} - -pub(crate) fn stringify_deserialize(data: String, field: &Field) -> Result { - // let _ = check_type_id(&data, field)?; - let s = match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), - FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), - FieldType::DateTime => DateDescription::from(field).str_from_cell_data(data), - FieldType::SingleSelect => SingleSelectDescription::from(field).str_from_cell_data(data), - FieldType::MultiSelect => MultiSelectDescription::from(field).str_from_cell_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).str_from_cell_data(data), - }; - Ok(s) -} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index 993e3401e3..fec4ea8d8c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -1,7 +1,7 @@ -mod cell_stringify; +mod cell_data_serde; mod row_builder; mod row_loader; -pub use cell_stringify::*; +pub use cell_data_serde::*; pub use row_builder::*; pub(crate) use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 7414c3ba8b..6bc231293a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,14 +1,14 @@ -use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta, DEFAULT_ROW_HEIGHT}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; pub struct CreateRowContextBuilder<'a> { #[allow(dead_code)] - fields: &'a [Field], + fields: &'a [FieldMeta], ctx: CreateRowContext, } impl<'a> CreateRowContextBuilder<'a> { - pub fn new(fields: &'a [Field]) -> Self { + pub fn new(fields: &'a [FieldMeta]) -> Self { let ctx = CreateRowContext { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 6f7640fb1e..aa114c3d07 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,7 +1,8 @@ -use crate::services::row::stringify_deserialize; -use flowy_grid_data_model::entities::{Cell, CellMeta, Field, Row, RowMeta, RowOrder}; +use crate::services::row::deserialize_cell_data; +use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; +use std::sync::Arc; pub(crate) struct RowIdsPerBlock { pub(crate) block_id: String, @@ -21,15 +22,16 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec>() } -pub(crate) fn make_rows(fields: &[Field], row_metas: Vec) -> Vec { +pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec>) -> Vec { let field_map = fields .iter() .map(|field| (&field.id, field)) - .collect::>(); + .collect::>(); - let make_row = |row_meta: RowMeta| { + let make_row = |row_meta: Arc| { let cell_by_field_id = row_meta .cell_by_field_id + .clone() .into_par_iter() .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) .collect::>(); @@ -45,9 +47,9 @@ pub(crate) fn make_rows(fields: &[Field], row_metas: Vec) -> Vec { } #[inline(always)] -fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { - let field = field_map.get(&field_id)?; - match stringify_deserialize(raw_cell.data, field) { +fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { + let field_meta = field_map.get(&field_id)?; + match deserialize_cell_data(raw_cell.data, field_meta) { Ok(content) => { let cell = Cell::new(&field_id, content); Some((field_id, cell)) @@ -59,15 +61,16 @@ fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: C } } -pub(crate) fn make_row_by_row_id(fields: &[Field], row_metas: Vec) -> HashMap { +pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>) -> HashMap { let field_map = fields .iter() .map(|field| (&field.id, field)) - .collect::>(); + .collect::>(); - let make_row = |row_meta: RowMeta| { + let make_row = |row_meta: Arc| { let cell_by_field_id = row_meta .cell_by_field_id + .clone() .into_par_iter() .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) .collect::>(); diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 360407b3b8..910589eb53 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use flowy_grid::services::cell::*; -use flowy_grid::services::row::{CreateRowContextBuilder, StringifyCellData}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; #[tokio::test] @@ -17,19 +17,19 @@ async fn grid_create_field() { let scripts = vec![ AssertFieldCount(2), CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldEqual { field_index: 2, - field: text_field, + field_meta: text_field, }, AssertFieldCount(3), CreateField { - field: single_select_field.clone(), + field_meta: single_select_field.clone(), }, AssertFieldEqual { field_index: 3, - field: single_select_field, + field_meta: single_select_field, }, AssertFieldCount(4), ]; @@ -42,11 +42,11 @@ async fn grid_create_duplicate_field() { let scripts = vec![ AssertFieldCount(2), CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldCount(3), CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldCount(3), ]; @@ -69,12 +69,12 @@ async fn grid_update_field_with_empty_change() { let scripts = vec![ CreateField { - field: single_select_field.clone(), + field_meta: single_select_field.clone(), }, UpdateField { changeset }, AssertFieldEqual { field_index: 2, - field: single_select_field, + field_meta: single_select_field, }, ]; GridEditorTest::new().await.run_scripts(scripts).await; @@ -105,12 +105,12 @@ async fn grid_update_field() { let scripts = vec![ CreateField { - field: single_select_field.clone(), + field_meta: single_select_field.clone(), }, UpdateField { changeset }, AssertFieldEqual { field_index: 2, - field: cloned_field, + field_meta: cloned_field, }, AssertGridMetaPad, ]; @@ -122,10 +122,10 @@ async fn grid_delete_field() { let text_field = create_text_field(); let scripts = vec![ CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldCount(3), - DeleteField { field: text_field }, + DeleteField { field_meta: text_field }, AssertFieldCount(2), ]; GridEditorTest::new().await.run_scripts(scripts).await; @@ -177,7 +177,7 @@ async fn grid_create_row() { #[tokio::test] async fn grid_create_row2() { let mut test = GridEditorTest::new().await; - let create_row_context = CreateRowContextBuilder::new(&test.fields).build(); + let create_row_context = CreateRowContextBuilder::new(&test.field_metas).build(); let scripts = vec![ AssertRowCount(3), CreateRow { @@ -191,7 +191,7 @@ async fn grid_create_row2() { #[tokio::test] async fn grid_update_row() { let mut test = GridEditorTest::new().await; - let context = CreateRowContextBuilder::new(&test.fields).build(); + let context = CreateRowContextBuilder::new(&test.field_metas).build(); let changeset = RowMetaChangeset { row_id: context.row_id.clone(), height: None, @@ -214,8 +214,8 @@ async fn grid_update_row() { #[tokio::test] async fn grid_delete_row() { let mut test = GridEditorTest::new().await; - let context_1 = CreateRowContextBuilder::new(&test.fields).build(); - let context_2 = CreateRowContextBuilder::new(&test.fields).build(); + let context_1 = CreateRowContextBuilder::new(&test.field_metas).build(); + let context_2 = CreateRowContextBuilder::new(&test.field_metas).build(); let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let scripts = vec![ AssertRowCount(3), @@ -240,26 +240,26 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_update_cell() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.fields); - for field in &test.fields { + let mut builder = CreateRowContextBuilder::new(&test.field_metas); + for field in &test.field_metas { match field.field_type { FieldType::RichText => { - builder = builder.add_cell(&field.id, "hello world".to_owned()); + let data = serialize_cell_data("hello world", field).unwrap(); + builder = builder.add_cell(&field.id, data); } FieldType::Number => { - let description = NumberDescription::from(field); - let data = description.str_to_cell_data("¥18,443").unwrap(); + let data = serialize_cell_data("¥18,443", field).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::DateTime => { - let description = DateDescription::from(field); - let data = description.str_to_cell_data("1647251762").unwrap(); + let data = serialize_cell_data("1647251762", field).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::SingleSelect => { let description = SingleSelectDescription::from(field); let options = description.options.first().unwrap(); - let data = description.str_to_cell_data(&options.id).unwrap(); + + let data = description.serialize_cell_data(&options.id).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::MultiSelect => { @@ -270,12 +270,11 @@ async fn grid_update_cell() { .map(|option| option.id.clone()) .collect::>() .join(","); - let data = description.str_to_cell_data(&options).unwrap(); + let data = description.serialize_cell_data(&options).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::Checkbox => { - let description = CheckboxDescription::from(field); - let data = description.str_to_cell_data("false").unwrap(); + let data = serialize_cell_data("false", field).unwrap(); builder = builder.add_cell(&field.id, data); } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index f123ecc9ed..777bad2949 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,7 +3,7 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowContext; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, + CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -14,18 +14,18 @@ use tokio::time::sleep; pub enum EditorScript { CreateField { - field: Field, + field_meta: FieldMeta, }, UpdateField { changeset: FieldChangeset, }, DeleteField { - field: Field, + field_meta: FieldMeta, }, AssertFieldCount(usize), AssertFieldEqual { field_index: usize, - field: Field, + field_meta: FieldMeta, }, CreateBlock { block: GridBlock, @@ -68,27 +68,31 @@ pub struct GridEditorTest { pub sdk: FlowySDKTest, pub grid_id: String, pub editor: Arc, - pub fields: Vec, + pub field_metas: Vec, pub grid_blocks: Vec, - pub row_metas: Vec, + pub row_metas: Vec>, } impl GridEditorTest { pub async fn new() -> Self { + Self::with_data("".to_owned()).await + } + + pub async fn with_data(data: String) -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new_grid_view(&sdk).await; + let test = ViewTest::new_grid_view(&sdk, data).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); - let fields = editor.get_fields(None).await.unwrap(); + let fields = editor.get_field_metas(None).await.unwrap(); let grid_blocks = editor.get_blocks().await.unwrap(); - let row_metas = editor.get_row_metas(&None).await.unwrap(); + let row_metas = editor.get_row_metas(None).await.unwrap(); let grid_id = test.view.id; Self { sdk, grid_id, editor, - fields, + field_metas: fields, grid_blocks, row_metas, } @@ -107,26 +111,28 @@ impl GridEditorTest { let _cache = rev_manager.revision_cache().await; match script { - EditorScript::CreateField { field } => { + EditorScript::CreateField { field_meta: field } => { self.editor.create_field(field).await.unwrap(); - self.fields = self.editor.get_fields(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); - self.fields = self.editor.get_fields(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } - EditorScript::DeleteField { field } => { + EditorScript::DeleteField { field_meta: field } => { self.editor.delete_field(&field.id).await.unwrap(); - self.fields = self.editor.get_fields(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } EditorScript::AssertFieldCount(count) => { - assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count); } - EditorScript::AssertFieldEqual { field_index, field } => { - let repeated_fields = self.editor.get_fields(None).await.unwrap(); - let compared_field = repeated_fields[field_index].clone(); - assert_eq!(compared_field, field); + EditorScript::AssertFieldEqual { + field_index, + field_meta, + } => { + let field_metas = self.editor.get_field_metas(None).await.unwrap(); + assert_eq!(field_metas[field_index].clone(), field_meta); } EditorScript::CreateBlock { block } => { self.editor.create_block(block).await.unwrap(); @@ -153,18 +159,18 @@ impl GridEditorTest { } EditorScript::CreateEmptyRow => { self.editor.create_row().await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::CreateRow { context } => { self.editor.insert_rows(vec![context]).await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { self.editor.delete_rows(row_ids).await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::AssertRow { changeset } => { @@ -180,7 +186,7 @@ impl GridEditorTest { } EditorScript::UpdateCell { changeset } => { self.editor.update_cell(changeset).await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); } EditorScript::AssertRowCount(count) => { assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); @@ -195,7 +201,7 @@ impl GridEditorTest { } } -pub fn create_text_field() -> Field { +pub fn create_text_field() -> FieldMeta { FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) @@ -203,7 +209,7 @@ pub fn create_text_field() -> Field { .build() } -pub fn create_single_select_field() -> Field { +pub fn create_single_select_field() -> FieldMeta { let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index 646ca04e0f..6bcd538a6b 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -308,7 +308,7 @@ impl FolderCouldServiceV1 for LocalServer { belongings: RepeatedView::default(), modified_time: time, create_time: time, - ext_data: params.ext_data, + ext_data: "".to_string(), thumbnail: params.thumbnail, plugin_type: params.plugin_type, }; diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 9c03c09bb5..03c4077831 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -26,11 +26,11 @@ pub struct ViewTest { impl ViewTest { #[allow(dead_code)] - pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType) -> Self { + pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: String) -> Self { let workspace = create_workspace(sdk, "Workspace", "").await; open_workspace(sdk, &workspace.id).await; let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await; - let view = create_view(sdk, &app.id, data_type).await; + let view = create_view(sdk, &app.id, data_type, data).await; Self { sdk: sdk.clone(), workspace, @@ -39,14 +39,12 @@ impl ViewTest { } } - #[allow(dead_code)] - pub async fn new_grid_view(sdk: &FlowySDKTest) -> Self { - Self::new(sdk, ViewDataType::Grid).await + pub async fn new_grid_view(sdk: &FlowySDKTest, data: String) -> Self { + Self::new(sdk, ViewDataType::Grid, data).await } - #[allow(dead_code)] pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self { - Self::new(sdk, ViewDataType::TextBlock).await + Self::new(sdk, ViewDataType::TextBlock, "".to_owned()).await } } @@ -93,15 +91,15 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s app } -async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType) -> View { +async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: String) -> View { let request = CreateViewPayload { belong_to_id: app_id.to_string(), name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), data_type, - ext_data: "".to_string(), plugin_type: 0, + data, }; let view = FolderEventBuilder::new(sdk.clone()) diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 790f9f3cfa..bd8379845a 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -50,27 +50,28 @@ impl GridBlockMetaPad { }) } - pub fn get_rows(&self, row_ids: Vec) -> CollaborateResult> { - let row_map = self - .rows - .iter() - .map(|row| (&row.id, row.clone())) - .collect::>>(); + pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { + match row_ids { + None => Ok(self.rows.iter().map(|row| row.clone()).collect::>()), + Some(row_ids) => { + let row_map = self + .rows + .iter() + .map(|row| (&row.id, row.clone())) + .collect::>>(); - Ok(row_ids - .iter() - .flat_map(|row_id| match row_map.get(row_id) { - None => { - tracing::error!("Can't find the row with id: {}", row_id); - None - } - Some(row) => Some((**row).clone()), - }) - .collect::>()) - } - - pub fn all_rows(&self) -> Vec { - self.rows.iter().map(|row| (**row).clone()).collect::>() + Ok(row_ids + .iter() + .flat_map(|row_id| match row_map.get(row_id) { + None => { + tracing::error!("Can't find the row with id: {}", row_id); + None + } + Some(row) => Some(row.clone()), + }) + .collect::>()) + } + } } pub fn number_of_rows(&self) -> i32 { diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 5fe63ca7d1..cbf31463a4 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,10 +1,10 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{Field, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { grid_id: String, - fields: Vec, + fields: Vec, grid_block: GridBlock, grid_block_meta: GridBlockMeta, } @@ -25,7 +25,7 @@ impl GridBuilder { } } - pub fn add_field(mut self, field: Field) -> Self { + pub fn add_field(mut self, field: FieldMeta) -> Self { self.fields.push(field); self } @@ -62,7 +62,7 @@ pub struct BuildGridInfo { } #[allow(dead_code)] -fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { +fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); for row in rows { let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); @@ -77,13 +77,13 @@ fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { #[cfg(test)] mod tests { use crate::client_grid::GridBuilder; - use flowy_grid_data_model::entities::{Field, FieldType, GridBlockMeta, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta}; #[test] fn create_default_grid_test() { let info = GridBuilder::new("1") - .add_field(Field::new("Name", "", FieldType::RichText)) - .add_field(Field::new("Tags", "", FieldType::SingleSelect)) + .add_field(FieldMeta::new("Name", "", FieldType::RichText)) + .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect)) .add_empty_row() .add_empty_row() .add_empty_row() diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index d7c9f13928..f303990546 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,7 +2,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, + FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -34,13 +34,13 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_field(&mut self, field: Field) -> CollaborateResult> { + pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.fields.contains(&field) { + if grid.fields.contains(&field_meta) { tracing::warn!("Duplicate grid field"); Ok(None) } else { - grid.fields.push(field); + grid.fields.push(field_meta); Ok(Some(())) } }) @@ -56,7 +56,15 @@ impl GridMetaPad { }) } - pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { + pub fn get_field_orders(&self) -> Vec { + self.grid_meta + .fields + .iter() + .map(|field_meta| FieldOrder::from(field_meta)) + .collect() + } + + pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { match field_orders { None => Ok(self.grid_meta.fields.clone()), Some(field_orders) => { @@ -65,7 +73,7 @@ impl GridMetaPad { .fields .iter() .map(|field| (&field.id, field)) - .collect::>(); + .collect::>(); let fields = field_orders .iter() @@ -76,7 +84,7 @@ impl GridMetaPad { } Some(field) => Some((*field).clone()), }) - .collect::>(); + .collect::>(); Ok(fields) } } @@ -131,7 +139,18 @@ impl GridMetaPad { tracing::warn!("Duplicate grid block"); Ok(None) } else { - grid.blocks.push(block); + match grid.blocks.last() { + None => grid.blocks.push(block), + Some(last_block) => { + if last_block.start_row_index > block.start_row_index + && last_block.len() > block.start_row_index + { + let msg = format!("GridBlock's start_row_index should be greater than the last_block's start_row_index and its len"); + return Err(CollaborateError::internal().context(msg)) + } + grid.blocks.push(block); + } + } Ok(Some(())) } }) @@ -168,7 +187,7 @@ impl GridMetaPad { self.delta.to_delta_str() } - pub fn fields(&self) -> &[Field] { + pub fn fields(&self) -> &[FieldMeta] { &self.grid_meta.fields } @@ -208,7 +227,7 @@ impl GridMetaPad { pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> where - F: FnOnce(&mut Field) -> CollaborateResult>, + F: FnOnce(&mut FieldMeta) -> CollaborateResult>, { self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { None => { diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index 8d6ac05406..bf7b99866c 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -124,10 +124,10 @@ pub struct CreateViewPayload { pub data_type: ViewDataType, #[pb(index = 6)] - pub ext_data: String, + pub plugin_type: i32, #[pb(index = 7)] - pub plugin_type: i32, + pub data: String, } #[derive(Default, ProtoBuf, Debug, Clone)] @@ -148,15 +148,12 @@ pub struct CreateViewParams { pub data_type: ViewDataType, #[pb(index = 6)] - pub ext_data: String, - - #[pb(index = 7)] pub view_id: String, - #[pb(index = 8)] + #[pb(index = 7)] pub data: String, - #[pb(index = 9)] + #[pb(index = 8)] pub plugin_type: i32, } @@ -167,12 +164,10 @@ impl TryInto for CreateViewPayload { let name = ViewName::parse(self.name)?.0; let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0; let view_id = uuid::Uuid::new_v4().to_string(); - let ext_data = ViewExtensionData::parse(self.ext_data)?.0; let thumbnail = match self.thumbnail { None => "".to_string(), Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0, }; - let data = "".to_string(); Ok(CreateViewParams { belong_to_id, @@ -180,9 +175,8 @@ impl TryInto for CreateViewPayload { desc: self.desc, data_type: self.data_type, thumbnail, - ext_data, view_id, - data, + data: self.data, plugin_type: self.plugin_type, }) } diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index bb38b794f2..15d8e2feaa 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -793,8 +793,8 @@ pub struct CreateViewPayload { pub name: ::std::string::String, pub desc: ::std::string::String, pub data_type: ViewDataType, - pub ext_data: ::std::string::String, pub plugin_type: i32, + pub data: ::std::string::String, // message oneof groups pub one_of_thumbnail: ::std::option::Option, // special fields @@ -960,33 +960,7 @@ impl CreateViewPayload { self.data_type = v; } - // string ext_data = 6; - - - pub fn get_ext_data(&self) -> &str { - &self.ext_data - } - pub fn clear_ext_data(&mut self) { - self.ext_data.clear(); - } - - // Param is passed by value, moved - pub fn set_ext_data(&mut self, v: ::std::string::String) { - self.ext_data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_ext_data(&mut self) -> &mut ::std::string::String { - &mut self.ext_data - } - - // Take field - pub fn take_ext_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.ext_data, ::std::string::String::new()) - } - - // int32 plugin_type = 7; + // int32 plugin_type = 6; pub fn get_plugin_type(&self) -> i32 { @@ -1000,6 +974,32 @@ impl CreateViewPayload { pub fn set_plugin_type(&mut self, v: i32) { self.plugin_type = v; } + + // string data = 7; + + + pub fn get_data(&self) -> &str { + &self.data + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::string::String) { + self.data = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::string::String { + &mut self.data + } + + // Take field + pub fn take_data(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.data, ::std::string::String::new()) + } } impl ::protobuf::Message for CreateViewPayload { @@ -1030,15 +1030,15 @@ impl ::protobuf::Message for CreateViewPayload { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)? }, 6 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?; - }, - 7 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } let tmp = is.read_int32()?; self.plugin_type = tmp; }, + 7 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1063,11 +1063,11 @@ impl ::protobuf::Message for CreateViewPayload { if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } - if !self.ext_data.is_empty() { - my_size += ::protobuf::rt::string_size(6, &self.ext_data); - } if self.plugin_type != 0 { - my_size += ::protobuf::rt::value_size(7, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + my_size += ::protobuf::rt::value_size(6, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + } + if !self.data.is_empty() { + my_size += ::protobuf::rt::string_size(7, &self.data); } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1094,11 +1094,11 @@ impl ::protobuf::Message for CreateViewPayload { if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } - if !self.ext_data.is_empty() { - os.write_string(6, &self.ext_data)?; - } if self.plugin_type != 0 { - os.write_int32(7, self.plugin_type)?; + os.write_int32(6, self.plugin_type)?; + } + if !self.data.is_empty() { + os.write_string(7, &self.data)?; } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1170,16 +1170,16 @@ impl ::protobuf::Message for CreateViewPayload { |m: &CreateViewPayload| { &m.data_type }, |m: &mut CreateViewPayload| { &mut m.data_type }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "ext_data", - |m: &CreateViewPayload| { &m.ext_data }, - |m: &mut CreateViewPayload| { &mut m.ext_data }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "plugin_type", |m: &CreateViewPayload| { &m.plugin_type }, |m: &mut CreateViewPayload| { &mut m.plugin_type }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "data", + |m: &CreateViewPayload| { &m.data }, + |m: &mut CreateViewPayload| { &mut m.data }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateViewPayload", fields, @@ -1201,8 +1201,8 @@ impl ::protobuf::Clear for CreateViewPayload { self.desc.clear(); self.one_of_thumbnail = ::std::option::Option::None; self.data_type = ViewDataType::TextBlock; - self.ext_data.clear(); self.plugin_type = 0; + self.data.clear(); self.unknown_fields.clear(); } } @@ -1227,7 +1227,6 @@ pub struct CreateViewParams { pub desc: ::std::string::String, pub thumbnail: ::std::string::String, pub data_type: ViewDataType, - pub ext_data: ::std::string::String, pub view_id: ::std::string::String, pub data: ::std::string::String, pub plugin_type: i32, @@ -1366,33 +1365,7 @@ impl CreateViewParams { self.data_type = v; } - // string ext_data = 6; - - - pub fn get_ext_data(&self) -> &str { - &self.ext_data - } - pub fn clear_ext_data(&mut self) { - self.ext_data.clear(); - } - - // Param is passed by value, moved - pub fn set_ext_data(&mut self, v: ::std::string::String) { - self.ext_data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_ext_data(&mut self) -> &mut ::std::string::String { - &mut self.ext_data - } - - // Take field - pub fn take_ext_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.ext_data, ::std::string::String::new()) - } - - // string view_id = 7; + // string view_id = 6; pub fn get_view_id(&self) -> &str { @@ -1418,7 +1391,7 @@ impl CreateViewParams { ::std::mem::replace(&mut self.view_id, ::std::string::String::new()) } - // string data = 8; + // string data = 7; pub fn get_data(&self) -> &str { @@ -1444,7 +1417,7 @@ impl CreateViewParams { ::std::mem::replace(&mut self.data, ::std::string::String::new()) } - // int32 plugin_type = 9; + // int32 plugin_type = 8; pub fn get_plugin_type(&self) -> i32 { @@ -1485,15 +1458,12 @@ impl ::protobuf::Message for CreateViewParams { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)? }, 6 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?; - }, - 7 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?; }, - 8 => { + 7 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; }, - 9 => { + 8 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -1527,17 +1497,14 @@ impl ::protobuf::Message for CreateViewParams { if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } - if !self.ext_data.is_empty() { - my_size += ::protobuf::rt::string_size(6, &self.ext_data); - } if !self.view_id.is_empty() { - my_size += ::protobuf::rt::string_size(7, &self.view_id); + my_size += ::protobuf::rt::string_size(6, &self.view_id); } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(8, &self.data); + my_size += ::protobuf::rt::string_size(7, &self.data); } if self.plugin_type != 0 { - my_size += ::protobuf::rt::value_size(9, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + my_size += ::protobuf::rt::value_size(8, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1560,17 +1527,14 @@ impl ::protobuf::Message for CreateViewParams { if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } - if !self.ext_data.is_empty() { - os.write_string(6, &self.ext_data)?; - } if !self.view_id.is_empty() { - os.write_string(7, &self.view_id)?; + os.write_string(6, &self.view_id)?; } if !self.data.is_empty() { - os.write_string(8, &self.data)?; + os.write_string(7, &self.data)?; } if self.plugin_type != 0 { - os.write_int32(9, self.plugin_type)?; + os.write_int32(8, self.plugin_type)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1635,11 +1599,6 @@ impl ::protobuf::Message for CreateViewParams { |m: &CreateViewParams| { &m.data_type }, |m: &mut CreateViewParams| { &mut m.data_type }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "ext_data", - |m: &CreateViewParams| { &m.ext_data }, - |m: &mut CreateViewParams| { &mut m.ext_data }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "view_id", |m: &CreateViewParams| { &m.view_id }, @@ -1676,7 +1635,6 @@ impl ::protobuf::Clear for CreateViewParams { self.desc.clear(); self.thumbnail.clear(); self.data_type = ViewDataType::TextBlock; - self.ext_data.clear(); self.view_id.clear(); self.data.clear(); self.plugin_type = 0; @@ -2880,32 +2838,32 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\t\x20\x01(\x03R\ncreateTime\x12\x19\n\x08ext_data\x18\n\x20\x01(\tR\ \x07extData\x12\x1c\n\tthumbnail\x18\x0b\x20\x01(\tR\tthumbnail\x12\x1f\ \n\x0bplugin_type\x18\x0c\x20\x01(\x05R\npluginType\"+\n\x0cRepeatedView\ - \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xf9\x01\n\ + \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xf2\x01\n\ \x11CreateViewPayload\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbel\ ongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\ \tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08d\ - ataType\x12\x19\n\x08ext_data\x18\x06\x20\x01(\tR\x07extData\x12\x1f\n\ - \x0bplugin_type\x18\x07\x20\x01(\x05R\npluginTypeB\x12\n\x10one_of_thumb\ - nail\"\x8f\x02\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\ - \x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\ - \x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\ - \x04\x20\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.Vi\ - ewDataTypeR\x08dataType\x12\x19\n\x08ext_data\x18\x06\x20\x01(\tR\x07ext\ - Data\x12\x17\n\x07view_id\x18\x07\x20\x01(\tR\x06viewId\x12\x12\n\x04dat\ - a\x18\x08\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\t\x20\x01(\ - \x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\x01\x20\x01(\ - \tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\x01\x20\x03(\ - \tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07view_id\x18\ - \x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04n\ - ame\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbn\ - ail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nameB\r\n\x0bone_\ - of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateViewParams\x12\ - \x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\ - \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ - \x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\ - \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*'\n\x0cVi\ - ewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01b\x06proto3\ + ataType\x12\x1f\n\x0bplugin_type\x18\x06\x20\x01(\x05R\npluginType\x12\ + \x12\n\x04data\x18\x07\x20\x01(\tR\x04dataB\x12\n\x10one_of_thumbnail\"\ + \xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01\ + (\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\ + \x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\ + \x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTy\ + peR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\x12\ + \x12\n\x04data\x18\x07\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\ + \x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\ + \x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\ + \x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07\ + view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\ + \tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\ + \x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nam\ + eB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateVi\ + ewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\ + \x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ + \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\ + mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\ + l*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01\ + b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index 9d51c50263..b66f778a71 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -23,8 +23,8 @@ message CreateViewPayload { string desc = 3; oneof one_of_thumbnail { string thumbnail = 4; }; ViewDataType data_type = 5; - string ext_data = 6; - int32 plugin_type = 7; + int32 plugin_type = 6; + string data = 7; } message CreateViewParams { string belong_to_id = 1; @@ -32,10 +32,9 @@ message CreateViewParams { string desc = 3; string thumbnail = 4; ViewDataType data_type = 5; - string ext_data = 6; - string view_id = 7; - string data = 8; - int32 plugin_type = 9; + string view_id = 6; + string data = 7; + int32 plugin_type = 8; } message ViewId { string value = 1; diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index ef84bfe104..e708dc8ee7 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,6 +1,7 @@ -use crate::entities::{Field, RowMeta}; +use crate::entities::{FieldMeta, FieldType, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; +use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { @@ -14,20 +15,82 @@ pub struct Grid { pub row_orders: Vec, } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct Field { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub desc: String, + + #[pb(index = 4)] + pub field_type: FieldType, + + #[pb(index = 5)] + pub frozen: bool, + + #[pb(index = 6)] + pub visibility: bool, + + #[pb(index = 7)] + pub width: i32, +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] pub field_id: String, } -impl std::convert::From<&Field> for FieldOrder { - fn from(field: &Field) -> Self { +impl std::convert::From<&FieldMeta> for FieldOrder { + fn from(field_meta: &FieldMeta) -> Self { Self { - field_id: field.id.clone(), + field_id: field_meta.id.clone(), } } } +impl std::convert::From for Field { + fn from(field_meta: FieldMeta) -> Self { + Self { + id: field_meta.id, + name: field_meta.name, + desc: field_meta.desc, + field_type: field_meta.field_type, + frozen: field_meta.frozen, + visibility: field_meta.visibility, + width: field_meta.width, + } + } +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedField { + #[pb(index = 1)] + pub items: Vec, +} +impl std::ops::Deref for RepeatedField { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedField { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +impl std::convert::From> for RepeatedField { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedFieldOrder { #[pb(index = 1)] @@ -59,6 +122,15 @@ impl std::convert::From<&RowMeta> for RowOrder { } } +impl std::convert::From<&Arc> for RowOrder { + fn from(row: &Arc) -> Self { + Self { + row_id: row.id.clone(), + block_id: row.block_id.clone(), + } + } +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedRowOrder { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 05de0efa05..c7cd8338c8 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -12,7 +12,7 @@ pub struct GridMeta { pub grid_id: String, #[pb(index = 2)] - pub fields: Vec, + pub fields: Vec, #[pb(index = 3)] pub blocks: Vec, @@ -30,6 +30,12 @@ pub struct GridBlock { pub row_count: i32, } +impl GridBlock { + pub fn len(&self) -> i32 { + self.start_row_index + self.row_count + } +} + impl GridBlock { pub fn new() -> Self { GridBlock { @@ -65,7 +71,7 @@ pub struct GridBlockMeta { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] -pub struct Field { +pub struct FieldMeta { #[pb(index = 1)] pub id: String, @@ -91,7 +97,7 @@ pub struct Field { pub type_options: String, } -impl Field { +impl FieldMeta { pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { Self { id: uuid::Uuid::new_v4().to_string(), @@ -133,30 +139,6 @@ pub struct FieldChangeset { pub type_options: Option, } -#[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedField { - #[pb(index = 1)] - pub items: Vec, -} -impl std::ops::Deref for RepeatedField { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedField { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedField { - fn from(items: Vec) -> Self { - Self { items } - } -} - #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] pub enum FieldType { RichText = 0, @@ -180,8 +162,8 @@ impl AsRef for FieldType { } impl From<&FieldType> for FieldType { - fn from(field: &FieldType) -> Self { - field.clone() + fn from(field_type: &FieldType) -> Self { + field_type.clone() } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index e7a7561068..4070675fd6 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -280,6 +280,385 @@ impl ::protobuf::reflect::ProtobufValue for Grid { } } +#[derive(PartialEq,Clone,Default)] +pub struct Field { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + pub field_type: super::meta::FieldType, + pub frozen: bool, + pub visibility: bool, + pub width: i32, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Field { + fn default() -> &'a Field { + ::default_instance() + } +} + +impl Field { + pub fn new() -> Field { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string desc = 3; + + + pub fn get_desc(&self) -> &str { + &self.desc + } + pub fn clear_desc(&mut self) { + self.desc.clear(); + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.desc = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + &mut self.desc + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.desc, ::std::string::String::new()) + } + + // .FieldType field_type = 4; + + + pub fn get_field_type(&self) -> super::meta::FieldType { + self.field_type + } + pub fn clear_field_type(&mut self) { + self.field_type = super::meta::FieldType::RichText; + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: super::meta::FieldType) { + self.field_type = v; + } + + // bool frozen = 5; + + + pub fn get_frozen(&self) -> bool { + self.frozen + } + pub fn clear_frozen(&mut self) { + self.frozen = false; + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.frozen = v; + } + + // bool visibility = 6; + + + pub fn get_visibility(&self) -> bool { + self.visibility + } + pub fn clear_visibility(&mut self) { + self.visibility = false; + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.visibility = v; + } + + // int32 width = 7; + + + pub fn get_width(&self) -> i32 { + self.width + } + pub fn clear_width(&mut self) { + self.width = 0; + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.width = v; + } +} + +impl ::protobuf::Message for Field { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; + }, + 4 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.frozen = tmp; + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.visibility = tmp; + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.width = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.name); + } + if !self.desc.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.desc); + } + if self.field_type != super::meta::FieldType::RichText { + my_size += ::protobuf::rt::enum_size(4, self.field_type); + } + if self.frozen != false { + my_size += 2; + } + if self.visibility != false { + my_size += 2; + } + if self.width != 0 { + my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.name.is_empty() { + os.write_string(2, &self.name)?; + } + if !self.desc.is_empty() { + os.write_string(3, &self.desc)?; + } + if self.field_type != super::meta::FieldType::RichText { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + if self.frozen != false { + os.write_bool(5, self.frozen)?; + } + if self.visibility != false { + os.write_bool(6, self.visibility)?; + } + if self.width != 0 { + os.write_int32(7, self.width)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Field { + Field::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &Field| { &m.id }, + |m: &mut Field| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Field| { &m.name }, + |m: &mut Field| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "desc", + |m: &Field| { &m.desc }, + |m: &mut Field| { &mut m.desc }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "field_type", + |m: &Field| { &m.field_type }, + |m: &mut Field| { &mut m.field_type }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "frozen", + |m: &Field| { &m.frozen }, + |m: &mut Field| { &mut m.frozen }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "visibility", + |m: &Field| { &m.visibility }, + |m: &mut Field| { &mut m.visibility }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "width", + |m: &Field| { &m.width }, + |m: &mut Field| { &mut m.width }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Field", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Field { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Field::new) + } +} + +impl ::protobuf::Clear for Field { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.desc.clear(); + self.field_type = super::meta::FieldType::RichText; + self.frozen = false; + self.visibility = false; + self.width = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Field { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Field { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -439,6 +818,172 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedField { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedField { + fn default() -> &'a RepeatedField { + ::default_instance() + } +} + +impl RepeatedField { + pub fn new() -> RepeatedField { + ::std::default::Default::default() + } + + // repeated .Field items = 1; + + + pub fn get_items(&self) -> &[Field] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedField { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedField { + RepeatedField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedField| { &m.items }, + |m: &mut RepeatedField| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedField::new) + } +} + +impl ::protobuf::Clear for RepeatedField { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedFieldOrder { // message fields @@ -2321,29 +2866,35 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrderR\x0bfieldOr\ - ders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\trowOrders\"'\ - \n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"7\n\ - \x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOr\ - derR\x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10R\ - epeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05\ - items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\ - \n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\ - \rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\ - \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ - \x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\ - \x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05ite\ - ms\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x18\n\x07content\x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ - ad\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\ - \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orde\ - rs\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ - \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ - rsb\x06proto3\ + \n\ngrid.proto\x1a\nmeta.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ + \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ + erR\x0bfieldOrders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\ + \trowOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ + id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\ + \x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.Fiel\ + dTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\ + \x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05wi\ + dth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_i\ + d\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ + \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"<\n\x08\ + RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ + lock_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10RepeatedRowOrder\x12\x1f\ + \n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Ro\ + w\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\ + \x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\ + \x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldId\ + Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ + \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\ + \x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\";\n\x04Cell\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ + \x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPayload\x12\x12\n\x04n\ + ame\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ + \x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\ + \x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\ + \x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\x0fQueryRowPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\ + \x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrdersb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index c8146c452a..bd01ee6cf6 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -27,7 +27,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, - pub fields: ::protobuf::RepeatedField, + pub fields: ::protobuf::RepeatedField, pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -71,10 +71,10 @@ impl GridMeta { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // repeated .Field fields = 2; + // repeated .FieldMeta fields = 2; - pub fn get_fields(&self) -> &[Field] { + pub fn get_fields(&self) -> &[FieldMeta] { &self.fields } pub fn clear_fields(&mut self) { @@ -82,17 +82,17 @@ impl GridMeta { } // Param is passed by value, moved - pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { self.fields = v; } // Mutable pointer to the field. - pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.fields } // Take field - pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { + pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } @@ -235,7 +235,7 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.grid_id }, |m: &mut GridMeta| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "fields", |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, @@ -718,7 +718,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } #[derive(PartialEq,Clone,Default)] -pub struct Field { +pub struct FieldMeta { // message fields pub id: ::std::string::String, pub name: ::std::string::String, @@ -733,14 +733,14 @@ pub struct Field { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a Field { - fn default() -> &'a Field { - ::default_instance() +impl<'a> ::std::default::Default for &'a FieldMeta { + fn default() -> &'a FieldMeta { + ::default_instance() } } -impl Field { - pub fn new() -> Field { +impl FieldMeta { + pub fn new() -> FieldMeta { ::std::default::Default::default() } @@ -909,7 +909,7 @@ impl Field { } } -impl ::protobuf::Message for Field { +impl ::protobuf::Message for FieldMeta { fn is_initialized(&self) -> bool { true } @@ -1050,8 +1050,8 @@ impl ::protobuf::Message for Field { Self::descriptor_static() } - fn new() -> Field { - Field::new() + fn new() -> FieldMeta { + FieldMeta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1060,59 +1060,59 @@ impl ::protobuf::Message for Field { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &Field| { &m.id }, - |m: &mut Field| { &mut m.id }, + |m: &FieldMeta| { &m.id }, + |m: &mut FieldMeta| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "name", - |m: &Field| { &m.name }, - |m: &mut Field| { &mut m.name }, + |m: &FieldMeta| { &m.name }, + |m: &mut FieldMeta| { &mut m.name }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "desc", - |m: &Field| { &m.desc }, - |m: &mut Field| { &mut m.desc }, + |m: &FieldMeta| { &m.desc }, + |m: &mut FieldMeta| { &mut m.desc }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "field_type", - |m: &Field| { &m.field_type }, - |m: &mut Field| { &mut m.field_type }, + |m: &FieldMeta| { &m.field_type }, + |m: &mut FieldMeta| { &mut m.field_type }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "frozen", - |m: &Field| { &m.frozen }, - |m: &mut Field| { &mut m.frozen }, + |m: &FieldMeta| { &m.frozen }, + |m: &mut FieldMeta| { &mut m.frozen }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "visibility", - |m: &Field| { &m.visibility }, - |m: &mut Field| { &mut m.visibility }, + |m: &FieldMeta| { &m.visibility }, + |m: &mut FieldMeta| { &mut m.visibility }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "width", - |m: &Field| { &m.width }, - |m: &mut Field| { &mut m.width }, + |m: &FieldMeta| { &m.width }, + |m: &mut FieldMeta| { &mut m.width }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "type_options", - |m: &Field| { &m.type_options }, - |m: &mut Field| { &mut m.type_options }, + |m: &FieldMeta| { &m.type_options }, + |m: &mut FieldMeta| { &mut m.type_options }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Field", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldMeta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static Field { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Field::new) + fn default_instance() -> &'static FieldMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldMeta::new) } } -impl ::protobuf::Clear for Field { +impl ::protobuf::Clear for FieldMeta { fn clear(&mut self) { self.id.clear(); self.name.clear(); @@ -1126,13 +1126,13 @@ impl ::protobuf::Clear for Field { } } -impl ::std::fmt::Debug for Field { +impl ::std::fmt::Debug for FieldMeta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for Field { +impl ::protobuf::reflect::ProtobufValue for FieldMeta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1769,172 +1769,6 @@ impl ::protobuf::reflect::ProtobufValue for FieldChangeset { } } -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedField { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedField { - fn default() -> &'a RepeatedField { - ::default_instance() - } -} - -impl RepeatedField { - pub fn new() -> RepeatedField { - ::std::default::Default::default() - } - - // repeated .Field items = 1; - - - pub fn get_items(&self) -> &[Field] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedField { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedField { - RepeatedField::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedField| { &m.items }, - |m: &mut RepeatedField| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedField", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedField { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedField::new) - } -} - -impl ::protobuf::Clear for RepeatedField { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedField { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedField { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct AnyData { // message fields @@ -3302,19 +3136,19 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"g\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ + \n\nmeta.proto\"k\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ s\x12\"\n\x06blocks\x18\x03\x20\x03(\x0b2\n.GridBlockR\x06blocks\"`\n\tG\ ridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_i\ ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ - RowMetaR\x04rows\"\xdb\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ - R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ - \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ - FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ - n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ + RowMetaR\x04rows\"\xdf\x01\n\tFieldMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04des\ + c\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ + .FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froz\ + en\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05\ + width\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\ _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\ \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\ @@ -3324,31 +3158,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\ \x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of\ _field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0c\ - one_of_widthB\x15\n\x13one_of_type_options\"-\n\rRepeatedField\x12\x1c\n\ - \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\ - \x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\ - \x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\ - \x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByF\ - ieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\ - \x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\ - \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ - \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\ - \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\ - \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\ - field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ - llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ - \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ - \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\ - \x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\ - \x02\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04\ - dataB\r\n\x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\ - \n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingle\ - Select\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\ - \x10\x05b\x06proto3\ + one_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyData\x12\x17\n\x07\ + type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01\ + (\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\ + \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntr\ + yR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\ + \x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12CellB\ + yFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05v\ + alue\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\n\ + \x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ + ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ + \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ + dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ + \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\x08Cell\ + Meta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04d\ + ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\ + ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\ + (\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\ + \x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Nu\ + mber\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ + \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ + proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 4e395edc92..66dba465f6 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -1,13 +1,26 @@ syntax = "proto3"; +import "meta.proto"; message Grid { string id = 1; repeated FieldOrder field_orders = 2; repeated RowOrder row_orders = 3; } +message Field { + string id = 1; + string name = 2; + string desc = 3; + FieldType field_type = 4; + bool frozen = 5; + bool visibility = 6; + int32 width = 7; +} message FieldOrder { string field_id = 1; } +message RepeatedField { + repeated Field items = 1; +} message RepeatedFieldOrder { repeated FieldOrder items = 1; } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 77185fff5d..32fc3896ac 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -2,7 +2,7 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; - repeated Field fields = 2; + repeated FieldMeta fields = 2; repeated GridBlock blocks = 3; } message GridBlock { @@ -14,7 +14,7 @@ message GridBlockMeta { string block_id = 1; repeated RowMeta rows = 2; } -message Field { +message FieldMeta { string id = 1; string name = 2; string desc = 3; @@ -34,9 +34,6 @@ message FieldChangeset { oneof one_of_width { int32 width = 7; }; oneof one_of_type_options { string type_options = 8; }; } -message RepeatedField { - repeated Field items = 1; -} message AnyData { string type_id = 1; bytes value = 2; diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 49780e2a52..0847950b98 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -31,8 +31,8 @@ fn grid_default_serde_test() { assert_eq!(json, r#"{"id":"1","fields":[],"blocks":[]}"#) } -fn create_field(field_id: &str) -> Field { - let mut field = Field::new("Text Field", "", FieldType::RichText); +fn create_field(field_id: &str) -> FieldMeta { + let mut field = FieldMeta::new("Text Field", "", FieldType::RichText); field.id = field_id.to_string(); field } From 47081f3095fec609baa10c3b04d48c48846ead6c Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 15 Mar 2022 19:00:28 +0800 Subject: [PATCH 040/179] chore: update grid test --- .../flowy-folder-data-model/view.pb.dart | 16 +- .../flowy-folder-data-model/view.pbjson.dart | 8 +- .../flowy-grid-data-model/meta.pb.dart | 73 +++++ .../flowy-grid-data-model/meta.pbjson.dart | 12 + frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-block/src/queue.rs | 4 +- frontend/rust-lib/flowy-folder/src/manager.rs | 6 +- .../src/services/folder_editor.rs | 4 +- .../src/services/persistence/mod.rs | 2 +- .../src/services/view/controller.rs | 13 +- frontend/rust-lib/flowy-grid/src/manager.rs | 35 ++- .../src/services/block_meta_editor.rs | 4 +- .../flowy-grid/src/services/grid_editor.rs | 12 +- frontend/rust-lib/flowy-grid/src/util.rs | 9 +- .../flowy-grid/tests/grid/grid_test.rs | 49 ++- .../rust-lib/flowy-grid/tests/grid/script.rs | 110 ++++++- frontend/rust-lib/flowy-sdk/Cargo.toml | 1 + .../flowy-sdk/src/deps_resolve/folder_deps.rs | 63 ++-- .../flowy-sync/src/conflict_resolve.rs | 4 +- frontend/rust-lib/flowy-test/src/helper.rs | 8 +- .../src/client_document/document_pad.rs | 5 +- .../src/client_folder/folder_pad.rs | 2 +- .../src/client_grid/block_pad.rs | 4 +- .../src/client_grid/grid_builder.rs | 86 ++---- .../src/client_grid/grid_pad.rs | 17 +- .../src/entities/view.rs | 4 +- .../src/protobuf/model/view.rs | 76 ++--- .../src/protobuf/proto/view.proto | 4 +- .../src/entities/meta.rs | 35 ++- .../src/protobuf/model/meta.rs | 291 +++++++++++++++++- .../src/protobuf/proto/meta.proto | 5 + shared-lib/lib-ot/src/core/delta/delta.rs | 2 +- 32 files changed, 746 insertions(+), 219 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index 350b5eac85..98882f444d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -276,7 +276,7 @@ class CreateViewPayload extends $pb.GeneratedMessage { ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) - ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) ..hasRequiredFields = false ; @@ -288,7 +288,7 @@ class CreateViewPayload extends $pb.GeneratedMessage { $core.String? thumbnail, ViewDataType? dataType, $core.int? pluginType, - $core.String? data, + $core.List<$core.int>? data, }) { final _result = create(); if (belongToId != null) { @@ -393,9 +393,9 @@ class CreateViewPayload extends $pb.GeneratedMessage { void clearPluginType() => clearField(6); @$pb.TagNumber(7) - $core.String get data => $_getSZ(6); + $core.List<$core.int> get data => $_getN(6); @$pb.TagNumber(7) - set data($core.String v) { $_setString(6, v); } + set data($core.List<$core.int> v) { $_setBytes(6, v); } @$pb.TagNumber(7) $core.bool hasData() => $_has(6); @$pb.TagNumber(7) @@ -410,7 +410,7 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') - ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -423,7 +423,7 @@ class CreateViewParams extends $pb.GeneratedMessage { $core.String? thumbnail, ViewDataType? dataType, $core.String? viewId, - $core.String? data, + $core.List<$core.int>? data, $core.int? pluginType, }) { final _result = create(); @@ -529,9 +529,9 @@ class CreateViewParams extends $pb.GeneratedMessage { void clearViewId() => clearField(6); @$pb.TagNumber(7) - $core.String get data => $_getSZ(6); + $core.List<$core.int> get data => $_getN(6); @$pb.TagNumber(7) - set data($core.String v) { $_setString(6, v); } + set data($core.List<$core.int> v) { $_setBytes(6, v); } @$pb.TagNumber(7) $core.bool hasData() => $_has(6); @$pb.TagNumber(7) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index 358cb41100..0f1949754f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -60,7 +60,7 @@ const CreateViewPayload$json = const { const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, const {'1': 'plugin_type', '3': 6, '4': 1, '5': 5, '10': 'pluginType'}, - const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 7, '4': 1, '5': 12, '10': 'data'}, ], '8': const [ const {'1': 'one_of_thumbnail'}, @@ -68,7 +68,7 @@ const CreateViewPayload$json = const { }; /// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgJUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw='); +final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgMUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw='); @$core.Deprecated('Use createViewParamsDescriptor instead') const CreateViewParams$json = const { '1': 'CreateViewParams', @@ -79,13 +79,13 @@ const CreateViewParams$json = const { const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, const {'1': 'view_id', '3': 6, '4': 1, '5': 9, '10': 'viewId'}, - const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 7, '4': 1, '5': 12, '10': 'data'}, const {'1': 'plugin_type', '3': 8, '4': 1, '5': 5, '10': 'pluginType'}, ], }; /// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ=='); +final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoDFIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ=='); @$core.Deprecated('Use viewIdDescriptor instead') const ViewId$json = const { '1': 'ViewId', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 49168b0274..0a0837d2df 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -1003,3 +1003,76 @@ class CellMetaChangeset extends $pb.GeneratedMessage { void clearData() => clearField(3); } +class BuildGridContext extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlock.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMeta', subBuilder: GridBlockMeta.create) + ..hasRequiredFields = false + ; + + BuildGridContext._() : super(); + factory BuildGridContext({ + $core.Iterable? fieldMetas, + GridBlock? gridBlock, + GridBlockMeta? gridBlockMeta, + }) { + final _result = create(); + if (fieldMetas != null) { + _result.fieldMetas.addAll(fieldMetas); + } + if (gridBlock != null) { + _result.gridBlock = gridBlock; + } + if (gridBlockMeta != null) { + _result.gridBlockMeta = gridBlockMeta; + } + return _result; + } + factory BuildGridContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BuildGridContext.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BuildGridContext clone() => BuildGridContext()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BuildGridContext copyWith(void Function(BuildGridContext) updates) => super.copyWith((message) => updates(message as BuildGridContext)) as BuildGridContext; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BuildGridContext create() => BuildGridContext._(); + BuildGridContext createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static BuildGridContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static BuildGridContext? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get fieldMetas => $_getList(0); + + @$pb.TagNumber(2) + GridBlock get gridBlock => $_getN(1); + @$pb.TagNumber(2) + set gridBlock(GridBlock v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasGridBlock() => $_has(1); + @$pb.TagNumber(2) + void clearGridBlock() => clearField(2); + @$pb.TagNumber(2) + GridBlock ensureGridBlock() => $_ensure(1); + + @$pb.TagNumber(3) + GridBlockMeta get gridBlockMeta => $_getN(2); + @$pb.TagNumber(3) + set gridBlockMeta(GridBlockMeta v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasGridBlockMeta() => $_has(2); + @$pb.TagNumber(3) + void clearGridBlockMeta() => clearField(3); + @$pb.TagNumber(3) + GridBlockMeta ensureGridBlockMeta() => $_ensure(2); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 3921f443c4..4dceb2116b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -191,3 +191,15 @@ const CellMetaChangeset$json = const { /// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); +@$core.Deprecated('Use buildGridContextDescriptor instead') +const BuildGridContext$json = const { + '1': 'BuildGridContext', + '2': const [ + const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, + const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlock', '10': 'gridBlock'}, + const {'1': 'grid_block_meta', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlockMeta'}, + ], +}; + +/// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEikKCmdyaWRfYmxvY2sYAiABKAsyCi5HcmlkQmxvY2tSCWdyaWRCbG9jaxI2Cg9ncmlkX2Jsb2NrX21ldGEYAyABKAsyDi5HcmlkQmxvY2tNZXRhUg1ncmlkQmxvY2tNZXRh'); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index a4c40e1735..30aa28a798 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1147,6 +1147,7 @@ dependencies = [ "flowy-database", "flowy-folder", "flowy-grid", + "flowy-grid-data-model", "flowy-net", "flowy-sync", "flowy-user", diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 94955f38d8..f7932e0850 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -175,7 +175,7 @@ impl EditBlockQueue { } async fn save_local_delta(&self, delta: RichTextDelta, md5: String) -> Result { - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let user_id = self.user.user_id()?; let revision = Revision::new( @@ -198,7 +198,7 @@ pub(crate) struct TextBlockRevisionCompactor(); impl RevisionCompactor for TextBlockRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index ffa6fc26cb..8fe34a2065 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -245,9 +245,11 @@ pub trait ViewDataProcessor { fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError>; - fn delta_str(&self, view_id: &str) -> FutureResult; + fn delta_bytes(&self, view_id: &str) -> FutureResult; - fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult; + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult; + + fn process_create_view_data(&self, user_id: &str, view_id: &str, data: Vec) -> FutureResult; fn data_type(&self) -> ViewDataType; } diff --git a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs index 7aaa1de7cd..48c83cc612 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -71,7 +71,7 @@ impl ClientFolderEditor { pub(crate) fn apply_change(&self, change: FolderChange) -> FlowyResult<()> { let FolderChange { delta, md5 } = change; let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let revision = Revision::new( &self.rev_manager.object_id, base_rev_id, @@ -128,6 +128,6 @@ struct FolderRevisionCompactor(); impl RevisionCompactor for FolderRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs index b05490b70a..16417934e0 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -115,7 +115,7 @@ impl FolderPersistence { pub async fn save_folder(&self, user_id: &str, folder_id: &FolderId, folder: FolderPad) -> FlowyResult<()> { let pool = self.database.db_pool()?; - let delta_data = initial_folder_delta(&folder)?.to_bytes(); + let delta_data = initial_folder_delta(&folder)?.to_delta_bytes(); let md5 = folder.md5(); let revision = Revision::new(folder_id.as_ref(), 0, 0, delta_data, user_id, md5); let record = RevisionRecord { diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index 2d943df032..c9851d6652 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -55,13 +55,14 @@ impl ViewController { #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] pub(crate) async fn create_view_from_params(&self, mut params: CreateViewParams) -> Result { let processor = self.get_data_processor(¶ms.data_type)?; - + let user_id = self.user.user_id()?; if params.data.is_empty() { - let user_id = self.user.user_id()?; let view_data = processor.create_default_view(&user_id, ¶ms.view_id).await?; - params.data = view_data; + params.data = view_data.to_vec(); } else { - let delta_data = Bytes::from(params.data.clone()); + let delta_data = processor + .process_create_view_data(&user_id, ¶ms.view_id, params.data.clone()) + .await?; let _ = self .create_view(¶ms.view_id, params.data_type.clone(), delta_data) .await?; @@ -162,14 +163,14 @@ impl ViewController { .await?; let processor = self.get_data_processor(&view.data_type)?; - let delta_str = processor.delta_str(view_id).await?; + let delta_bytes = processor.delta_bytes(view_id).await?; let duplicate_params = CreateViewParams { belong_to_id: view.belong_to_id.clone(), name: format!("{} (copy)", &view.name), desc: view.desc, thumbnail: view.thumbnail, data_type: view.data_type, - data: delta_str, + data: delta_bytes.to_vec(), view_id: uuid(), plugin_type: view.plugin_type, }; diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index fc79fcf5c0..28a246bd75 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,8 +1,11 @@ use crate::services::grid_editor::ClientGridEditor; use crate::services::kv_persistence::GridKVPersistence; +use bytes::Bytes; use dashmap::DashMap; -use flowy_collaboration::entities::revision::RepeatedRevision; +use flowy_collaboration::client_grid::{make_block_meta_delta, make_grid_delta}; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::{BuildGridContext, GridMeta}; use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; @@ -172,3 +175,33 @@ impl GridEditorMap { self.inner.remove(grid_id); } } + +pub async fn make_grid_view_data( + user_id: &str, + view_id: &str, + grid_manager: Arc, + build_context: BuildGridContext, +) -> FlowyResult { + let block_id = build_context.grid_block.id.clone(); + let grid_meta = GridMeta { + grid_id: view_id.to_string(), + fields: build_context.field_metas, + blocks: vec![build_context.grid_block], + }; + + let grid_meta_delta = make_grid_delta(&grid_meta); + let grid_delta_data = grid_meta_delta.to_delta_bytes(); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); + let _ = grid_manager.create_grid(view_id, repeated_revision).await?; + + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); + let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &block_id, block_meta_delta_data).into(); + let _ = grid_manager + .create_grid_block_meta(&block_id, repeated_revision) + .await?; + + Ok(grid_delta_data) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index c691e0b12c..fb72f8c34d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -280,7 +280,7 @@ impl ClientGridBlockMetaEditor { let GridBlockMetaChange { delta, md5 } = change; let user_id = self.user_id.clone(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let revision = Revision::new( &self.rev_manager.object_id, base_rev_id, @@ -323,6 +323,6 @@ struct GridBlockMetaRevisionCompactor(); impl RevisionCompactor for GridBlockMetaRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index e45dad5394..86c7a8fc0e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -61,6 +61,10 @@ impl ClientGridEditor { Ok(()) } + pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool { + self.grid_meta_pad.read().await.contain_field(&field_meta.id) + } + pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?; Ok(()) @@ -177,8 +181,8 @@ impl ClientGridEditor { Ok(grid_blocks) } - pub async fn delta_str(&self) -> String { - self.grid_meta_pad.read().await.delta_str() + pub async fn delta_bytes(&self) -> Bytes { + self.grid_meta_pad.read().await.delta_bytes() } async fn modify(&self, f: F) -> FlowyResult<()> @@ -199,7 +203,7 @@ impl ClientGridEditor { let GridChange { delta, md5 } = change; let user_id = self.user.user_id()?; let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let revision = Revision::new( &self.rev_manager.object_id, base_rev_id, @@ -256,6 +260,6 @@ struct GridRevisionCompactor(); impl RevisionCompactor for GridRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 80f942751a..e7417b5ea7 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,9 +1,9 @@ use crate::services::cell::*; use crate::services::field::*; -use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; -use flowy_grid_data_model::entities::FieldType; +use flowy_collaboration::client_grid::GridBuilder; +use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; -pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { +pub fn make_default_grid() -> BuildGridContext { let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) @@ -20,12 +20,11 @@ pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { .field_type(FieldType::SingleSelect) .build(); - GridBuilder::new(grid_id) + GridBuilder::default() .add_field(text_field) .add_field(single_select_field) .add_empty_row() .add_empty_row() .add_empty_row() .build() - .unwrap() } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 910589eb53..30469d406f 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,57 +4,56 @@ use flowy_grid::services::cell::*; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; -#[tokio::test] -async fn default_grid_test() { - let scripts = vec![AssertFieldCount(2), AssertGridMetaPad]; - GridEditorTest::new().await.run_scripts(scripts).await; -} - #[tokio::test] async fn grid_create_field() { + let mut test = GridEditorTest::new().await; let text_field = create_text_field(); let single_select_field = create_single_select_field(); + let scripts = vec![ - AssertFieldCount(2), CreateField { field_meta: text_field.clone(), }, AssertFieldEqual { - field_index: 2, + field_index: test.field_count, field_meta: text_field, }, - AssertFieldCount(3), + ]; + test.run_scripts(scripts).await; + + let scripts = vec![ CreateField { field_meta: single_select_field.clone(), }, AssertFieldEqual { - field_index: 3, + field_index: test.field_count, field_meta: single_select_field, }, - AssertFieldCount(4), ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_create_duplicate_field() { + let mut test = GridEditorTest::new().await; let text_field = create_text_field(); + let field_count = test.field_count; + let expected_field_count = field_count + 1; let scripts = vec![ - AssertFieldCount(2), CreateField { field_meta: text_field.clone(), }, - AssertFieldCount(3), CreateField { field_meta: text_field.clone(), }, - AssertFieldCount(3), + AssertFieldCount(expected_field_count), ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_update_field_with_empty_change() { + let mut test = GridEditorTest::new().await; let single_select_field = create_single_select_field(); let changeset = FieldChangeset { field_id: single_select_field.id.clone(), @@ -73,21 +72,21 @@ async fn grid_update_field_with_empty_change() { }, UpdateField { changeset }, AssertFieldEqual { - field_index: 2, + field_index: test.field_count, field_meta: single_select_field, }, ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_update_field() { + let mut test = GridEditorTest::new().await; let single_select_field = create_single_select_field(); let mut cloned_field = single_select_field.clone(); let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); single_select_type_options.options.push(SelectOption::new("Unknown")); - let changeset = FieldChangeset { field_id: single_select_field.id.clone(), name: None, @@ -109,26 +108,26 @@ async fn grid_update_field() { }, UpdateField { changeset }, AssertFieldEqual { - field_index: 2, + field_index: test.field_count, field_meta: cloned_field, }, - AssertGridMetaPad, ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_delete_field() { + let mut test = GridEditorTest::new().await; + let expected_field_count = test.field_count; let text_field = create_text_field(); let scripts = vec![ CreateField { field_meta: text_field.clone(), }, - AssertFieldCount(3), DeleteField { field_meta: text_field }, - AssertFieldCount(2), + AssertFieldCount(expected_field_count), ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 777bad2949..c49bf82a03 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,15 +1,22 @@ +use bytes::Bytes; +use flowy_collaboration::client_grid::GridBuilder; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; +use flowy_error::FlowyResult; +use flowy_grid::manager::{make_grid_view_data, GridManager}; use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowContext; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, + BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, + RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; use std::time::Duration; +use strum::{EnumCount, IntoEnumIterator}; use tokio::time::sleep; pub enum EditorScript { @@ -71,19 +78,18 @@ pub struct GridEditorTest { pub field_metas: Vec, pub grid_blocks: Vec, pub row_metas: Vec>, + pub field_count: usize, } impl GridEditorTest { pub async fn new() -> Self { - Self::with_data("".to_owned()).await - } - - pub async fn with_data(data: String) -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new_grid_view(&sdk, data).await; + let build_context = make_template_1_grid(); + let view_data: Bytes = build_context.try_into().unwrap(); + let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); - let fields = editor.get_field_metas(None).await.unwrap(); + let field_metas = editor.get_field_metas(None).await.unwrap(); let grid_blocks = editor.get_blocks().await.unwrap(); let row_metas = editor.get_row_metas(None).await.unwrap(); @@ -92,9 +98,10 @@ impl GridEditorTest { sdk, grid_id, editor, - field_metas: fields, + field_metas, grid_blocks, row_metas, + field_count: FieldType::COUNT, } } @@ -111,22 +118,30 @@ impl GridEditorTest { let _cache = rev_manager.revision_cache().await; match script { - EditorScript::CreateField { field_meta: field } => { - self.editor.create_field(field).await.unwrap(); + EditorScript::CreateField { field_meta } => { + if !self.editor.contain_field(&field_meta).await { + self.field_count += 1; + } + self.editor.create_field(field_meta).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + assert_eq!(self.field_count, self.field_metas.len()); } EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } - EditorScript::DeleteField { field_meta: field } => { - self.editor.delete_field(&field.id).await.unwrap(); + EditorScript::DeleteField { field_meta } => { + if self.editor.contain_field(&field_meta).await { + self.field_count -= 1; + } + + self.editor.delete_field(&field_meta.id).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + assert_eq!(self.field_count, self.field_metas.len()); } EditorScript::AssertFieldCount(count) => { assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count); } - EditorScript::AssertFieldEqual { field_index, field_meta, @@ -220,3 +235,72 @@ pub fn create_single_select_field() -> FieldMeta { .field_type(FieldType::SingleSelect) .build() } + +fn make_template_1_grid() -> BuildGridContext { + let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) + .name("Name") + .visibility(true) + .field_type(FieldType::RichText) + .build(); + + // Single Select + let single_select = SingleSelectTypeOptionsBuilder::default() + .option(SelectOption::new("Live")) + .option(SelectOption::new("Completed")) + .option(SelectOption::new("Planned")) + .option(SelectOption::new("Paused")); + let single_select_field = FieldBuilder::new(single_select) + .name("Status") + .visibility(true) + .field_type(FieldType::SingleSelect) + .build(); + + // MultiSelect + let multi_select = MultiSelectTypeOptionsBuilder::default() + .option(SelectOption::new("Google")) + .option(SelectOption::new("Facebook")) + .option(SelectOption::new("Twitter")); + let multi_select_field = FieldBuilder::new(multi_select) + .name("Platform") + .visibility(true) + .field_type(FieldType::MultiSelect) + .build(); + + // Number + let number = NumberTypeOptionsBuilder::default().set_format(NumberFormat::USD); + let number_field = FieldBuilder::new(number) + .name("Price") + .visibility(true) + .field_type(FieldType::Number) + .build(); + + // Date + let date = DateTypeOptionsBuilder::default() + .date_format(DateFormat::US) + .time_format(TimeFormat::TwentyFourHour); + let date_field = FieldBuilder::new(date) + .name("Time") + .visibility(true) + .field_type(FieldType::DateTime) + .build(); + + // Checkbox + let checkbox = CheckboxTypeOptionsBuilder::default(); + let checkbox_field = FieldBuilder::new(checkbox) + .name("is done") + .visibility(true) + .field_type(FieldType::Checkbox) + .build(); + + GridBuilder::default() + .add_field(text_field) + .add_field(single_select_field) + .add_field(multi_select_field) + .add_field(number_field) + .add_field(date_field) + .add_field(checkbox_field) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() +} diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 75791d0279..75ab8a3b5c 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -12,6 +12,7 @@ flowy-user = { path = "../flowy-user" } flowy-net = { path = "../flowy-net" } flowy-folder = { path = "../flowy-folder", default-features = false } flowy-grid = { path = "../flowy-grid", default-features = false } +flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } flowy-database = { path = "../flowy-database" } flowy-block = { path = "../flowy-block", default-features = false } flowy-sync = { path = "../flowy-sync" } diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 0646dbcc5b..89346eaf35 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -4,6 +4,7 @@ use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; +use flowy_folder::errors::FlowyResult; use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; use flowy_folder::prelude::ViewDataType; use flowy_folder::{ @@ -11,8 +12,9 @@ use flowy_folder::{ event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, manager::FolderManager, }; -use flowy_grid::manager::GridManager; +use flowy_grid::manager::{make_grid_view_data, GridManager}; use flowy_grid::util::make_default_grid; +use flowy_grid_data_model::entities::BuildGridContext; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -23,6 +25,7 @@ use futures_core::future::BoxFuture; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use std::collections::HashMap; +use std::convert::TryFrom; use std::{convert::TryInto, sync::Arc}; pub struct FolderDepsResolver(); @@ -168,29 +171,39 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { }) } - fn delta_str(&self, view_id: &str) -> FutureResult { + fn delta_bytes(&self, view_id: &str) -> FutureResult { let view_id = view_id.to_string(); let manager = self.0.clone(); FutureResult::new(async move { let editor = manager.open_block(view_id).await?; - let delta_str = editor.delta_str().await?; - Ok(delta_str) + let delta_bytes = Bytes::from(editor.delta_str().await?); + Ok(delta_bytes) }) } - fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { let user_id = user_id.to_string(); let view_id = view_id.to_string(); let manager = self.0.clone(); FutureResult::new(async move { let view_data = initial_quill_delta_string(); - let delta_data = Bytes::from(view_data.clone()); - let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, &view_id, delta_data).into(); + let delta_data = Bytes::from(view_data); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &view_id, delta_data.clone()).into(); let _ = manager.create_block(view_id, repeated_revision).await?; - Ok(view_data) + Ok(delta_data) }) } + fn process_create_view_data( + &self, + _user_id: &str, + _view_id: &str, + data: Vec, + ) -> FutureResult { + FutureResult::new(async move { Ok(Bytes::from(data)) }) + } + fn data_type(&self) -> ViewDataType { ViewDataType::TextBlock } @@ -230,36 +243,34 @@ impl ViewDataProcessor for GridViewDataProcessor { }) } - fn delta_str(&self, view_id: &str) -> FutureResult { + fn delta_bytes(&self, view_id: &str) -> FutureResult { let view_id = view_id.to_string(); let grid_manager = self.0.clone(); FutureResult::new(async move { let editor = grid_manager.open_grid(view_id).await?; - let delta_str = editor.delta_str().await; - Ok(delta_str) + let delta_bytes = editor.delta_bytes().await; + Ok(delta_bytes) }) } - fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { - let info = make_default_grid(view_id); + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + let build_context = make_default_grid(); + let user_id = user_id.to_string(); + let view_id = view_id.to_string(); + let grid_manager = self.0.clone(); + + FutureResult::new(async move { make_grid_view_data(&user_id, &view_id, grid_manager, build_context).await }) + } + + fn process_create_view_data(&self, user_id: &str, view_id: &str, data: Vec) -> FutureResult { let user_id = user_id.to_string(); let view_id = view_id.to_string(); let grid_manager = self.0.clone(); FutureResult::new(async move { - let grid_delta_data = Bytes::from(info.grid_delta.to_delta_str()); - let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, &view_id, grid_delta_data).into(); - let _ = grid_manager.create_grid(&view_id, repeated_revision).await?; - - let block_meta_delta_data = Bytes::from(info.grid_block_meta_delta.to_delta_str()); - let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, &info.block_id, block_meta_delta_data).into(); - let _ = grid_manager - .create_grid_block_meta(&info.block_id, repeated_revision) - .await?; - - Ok(info.grid_delta.to_delta_str()) + let bytes = Bytes::from(data); + let build_context = BuildGridContext::try_from(bytes)?; + make_grid_view_data(&user_id, &view_id, grid_manager, build_context).await }) } diff --git a/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs b/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs index 817b77bd88..a4f4f6c818 100644 --- a/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs +++ b/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs @@ -154,7 +154,7 @@ where &rev_manager.object_id, base_rev_id, rev_id, - client_delta.to_bytes(), + client_delta.to_delta_bytes(), user_id, md5.clone(), ); @@ -166,7 +166,7 @@ where &rev_manager.object_id, base_rev_id, rev_id, - server_delta.to_bytes(), + server_delta.to_delta_bytes(), user_id, md5, ); diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 03c4077831..f83f245754 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -26,7 +26,7 @@ pub struct ViewTest { impl ViewTest { #[allow(dead_code)] - pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: String) -> Self { + pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: Vec) -> Self { let workspace = create_workspace(sdk, "Workspace", "").await; open_workspace(sdk, &workspace.id).await; let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await; @@ -39,12 +39,12 @@ impl ViewTest { } } - pub async fn new_grid_view(sdk: &FlowySDKTest, data: String) -> Self { + pub async fn new_grid_view(sdk: &FlowySDKTest, data: Vec) -> Self { Self::new(sdk, ViewDataType::Grid, data).await } pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self { - Self::new(sdk, ViewDataType::TextBlock, "".to_owned()).await + Self::new(sdk, ViewDataType::TextBlock, vec![]).await } } @@ -91,7 +91,7 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s app } -async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: String) -> View { +async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: Vec) -> View { let request = CreateViewPayload { belong_to_id: app_id.to_string(), name: "View A".to_string(), diff --git a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs index 4807d9869c..72b52f6415 100644 --- a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs @@ -6,6 +6,7 @@ use crate::{ }, errors::CollaborateError, }; +use bytes::Bytes; use lib_ot::{ core::*, rich_text::{RichTextAttribute, RichTextDelta}, @@ -62,8 +63,8 @@ impl ClientDocument { self.delta.to_delta_str() } - pub fn to_bytes(&self) -> Vec { - self.delta.clone().to_bytes().to_vec() + pub fn to_bytes(&self) -> Bytes { + self.delta.to_delta_bytes() } pub fn to_plain_string(&self) -> String { diff --git a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs index 4fd8a1982e..fd79fb8af0 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs @@ -268,7 +268,7 @@ impl FolderPad { } pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) + md5(&self.delta.to_delta_bytes()) } pub fn to_json(&self) -> CollaborateResult { diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index bd8379845a..fafa2d45ce 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -144,7 +144,7 @@ impl GridBlockMetaPad { } pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) + md5(&self.delta.to_delta_bytes()) } pub fn delta_str(&self) -> String { @@ -165,7 +165,7 @@ pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta { pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision { let delta = make_block_meta_delta(block_meta); - let bytes = delta.to_bytes(); + let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); revision.into() } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index cbf31463a4..42faa4abda 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,66 +1,37 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { - grid_id: String, - fields: Vec, - grid_block: GridBlock, - grid_block_meta: GridBlockMeta, + build_context: BuildGridContext, +} + +impl std::default::Default for GridBuilder { + fn default() -> Self { + Self { + build_context: Default::default(), + } + } } impl GridBuilder { - pub fn new(grid_id: &str) -> Self { - let grid_block = GridBlock::new(); - let grid_block_meta = GridBlockMeta { - block_id: grid_block.id.clone(), - rows: vec![], - }; - - Self { - grid_id: grid_id.to_owned(), - fields: vec![], - grid_block, - grid_block_meta, - } - } - pub fn add_field(mut self, field: FieldMeta) -> Self { - self.fields.push(field); + self.build_context.field_metas.push(field); self } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.grid_block.id); - self.grid_block_meta.rows.push(row); - self.grid_block.row_count += 1; + let row = RowMeta::new(&self.build_context.grid_block.id); + self.build_context.grid_block_meta.rows.push(row); + self.build_context.grid_block.row_count += 1; self } - pub fn build(self) -> CollaborateResult { - let block_id = self.grid_block.id.clone(); - let grid_meta = GridMeta { - grid_id: self.grid_id, - fields: self.fields, - blocks: vec![self.grid_block], - }; - // let _ = check_rows(&self.fields, &self.rows)?; - let grid_delta = make_grid_delta(&grid_meta); - let grid_block_meta_delta = make_block_meta_delta(&self.grid_block_meta); - Ok(BuildGridInfo { - grid_delta, - block_id, - grid_block_meta_delta, - }) + pub fn build(self) -> BuildGridContext { + self.build_context } } -pub struct BuildGridInfo { - pub grid_delta: GridMetaDelta, - pub block_id: String, - pub grid_block_meta_delta: GridBlockMetaDelta, -} - #[allow(dead_code)] fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); @@ -76,28 +47,31 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { #[cfg(test)] mod tests { - use crate::client_grid::GridBuilder; + + use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta}; #[test] fn create_default_grid_test() { - let info = GridBuilder::new("1") + let grid_id = "1".to_owned(); + let build_context = GridBuilder::default() .add_field(FieldMeta::new("Name", "", FieldType::RichText)) .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect)) .add_empty_row() .add_empty_row() .add_empty_row() - .build() - .unwrap(); + .build(); - let grid_meta: GridMeta = serde_json::from_str(&info.grid_delta.to_str().unwrap()).unwrap(); - assert_eq!(grid_meta.fields.len(), 2); - assert_eq!(grid_meta.blocks.len(), 1); + let grid_meta = GridMeta { + grid_id: grid_id.clone(), + fields: build_context.field_metas, + blocks: vec![build_context.grid_block], + }; - let grid_block_meta: GridBlockMeta = - serde_json::from_str(&info.grid_block_meta_delta.to_str().unwrap()).unwrap(); - assert_eq!(grid_block_meta.rows.len(), 3); + let grid_meta_delta = make_grid_delta(&grid_meta); + let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); - assert_eq!(grid_meta.blocks[0].id, grid_block_meta.block_id); + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); + let _: GridBlockMeta = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index f303990546..bcae5144a8 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,6 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; +use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; @@ -56,6 +57,14 @@ impl GridMetaPad { }) } + pub fn contain_field(&self, field_id: &str) -> bool { + self.grid_meta + .fields + .iter() + .find(|field| &field.id == field_id) + .is_some() + } + pub fn get_field_orders(&self) -> Vec { self.grid_meta .fields @@ -180,13 +189,17 @@ impl GridMetaPad { } pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) + md5(&self.delta.to_delta_bytes()) } pub fn delta_str(&self) -> String { self.delta.to_delta_str() } + pub fn delta_bytes(&self) -> Bytes { + self.delta.to_delta_bytes() + } + pub fn fields(&self) -> &[FieldMeta] { &self.grid_meta.fields } @@ -258,7 +271,7 @@ pub fn make_grid_delta(grid_meta: &GridMeta) -> GridMetaDelta { pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision { let delta = make_grid_delta(grid_meta); - let bytes = delta.to_bytes(); + let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes); revision.into() } diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index bf7b99866c..ac346188ce 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -127,7 +127,7 @@ pub struct CreateViewPayload { pub plugin_type: i32, #[pb(index = 7)] - pub data: String, + pub data: Vec, } #[derive(Default, ProtoBuf, Debug, Clone)] @@ -151,7 +151,7 @@ pub struct CreateViewParams { pub view_id: String, #[pb(index = 7)] - pub data: String, + pub data: Vec, #[pb(index = 8)] pub plugin_type: i32, diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index 15d8e2feaa..9f19e18f0c 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -794,7 +794,7 @@ pub struct CreateViewPayload { pub desc: ::std::string::String, pub data_type: ViewDataType, pub plugin_type: i32, - pub data: ::std::string::String, + pub data: ::std::vec::Vec, // message oneof groups pub one_of_thumbnail: ::std::option::Option, // special fields @@ -975,10 +975,10 @@ impl CreateViewPayload { self.plugin_type = v; } - // string data = 7; + // bytes data = 7; - pub fn get_data(&self) -> &str { + pub fn get_data(&self) -> &[u8] { &self.data } pub fn clear_data(&mut self) { @@ -986,19 +986,19 @@ impl CreateViewPayload { } // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { + pub fn set_data(&mut self, v: ::std::vec::Vec) { self.data = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { &mut self.data } // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) + pub fn take_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) } } @@ -1037,7 +1037,7 @@ impl ::protobuf::Message for CreateViewPayload { self.plugin_type = tmp; }, 7 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -1067,7 +1067,7 @@ impl ::protobuf::Message for CreateViewPayload { my_size += ::protobuf::rt::value_size(6, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(7, &self.data); + my_size += ::protobuf::rt::bytes_size(7, &self.data); } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1098,7 +1098,7 @@ impl ::protobuf::Message for CreateViewPayload { os.write_int32(6, self.plugin_type)?; } if !self.data.is_empty() { - os.write_string(7, &self.data)?; + os.write_bytes(7, &self.data)?; } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1175,7 +1175,7 @@ impl ::protobuf::Message for CreateViewPayload { |m: &CreateViewPayload| { &m.plugin_type }, |m: &mut CreateViewPayload| { &mut m.plugin_type }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( "data", |m: &CreateViewPayload| { &m.data }, |m: &mut CreateViewPayload| { &mut m.data }, @@ -1228,7 +1228,7 @@ pub struct CreateViewParams { pub thumbnail: ::std::string::String, pub data_type: ViewDataType, pub view_id: ::std::string::String, - pub data: ::std::string::String, + pub data: ::std::vec::Vec, pub plugin_type: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -1391,10 +1391,10 @@ impl CreateViewParams { ::std::mem::replace(&mut self.view_id, ::std::string::String::new()) } - // string data = 7; + // bytes data = 7; - pub fn get_data(&self) -> &str { + pub fn get_data(&self) -> &[u8] { &self.data } pub fn clear_data(&mut self) { @@ -1402,19 +1402,19 @@ impl CreateViewParams { } // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { + pub fn set_data(&mut self, v: ::std::vec::Vec) { self.data = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { &mut self.data } // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) + pub fn take_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) } // int32 plugin_type = 8; @@ -1461,7 +1461,7 @@ impl ::protobuf::Message for CreateViewParams { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?; }, 7 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; }, 8 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -1501,7 +1501,7 @@ impl ::protobuf::Message for CreateViewParams { my_size += ::protobuf::rt::string_size(6, &self.view_id); } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(7, &self.data); + my_size += ::protobuf::rt::bytes_size(7, &self.data); } if self.plugin_type != 0 { my_size += ::protobuf::rt::value_size(8, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); @@ -1531,7 +1531,7 @@ impl ::protobuf::Message for CreateViewParams { os.write_string(6, &self.view_id)?; } if !self.data.is_empty() { - os.write_string(7, &self.data)?; + os.write_bytes(7, &self.data)?; } if self.plugin_type != 0 { os.write_int32(8, self.plugin_type)?; @@ -1604,7 +1604,7 @@ impl ::protobuf::Message for CreateViewParams { |m: &CreateViewParams| { &m.view_id }, |m: &mut CreateViewParams| { &mut m.view_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( "data", |m: &CreateViewParams| { &m.data }, |m: &mut CreateViewParams| { &mut m.data }, @@ -2844,22 +2844,22 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\ \tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08d\ ataType\x12\x1f\n\x0bplugin_type\x18\x06\x20\x01(\x05R\npluginType\x12\ - \x12\n\x04data\x18\x07\x20\x01(\tR\x04dataB\x12\n\x10one_of_thumbnail\"\ - \xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01\ - (\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\ - \x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\ - \x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTy\ - peR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\x12\ - \x12\n\x04data\x18\x07\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\ - \x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\ - \x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07\ - view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\ - \tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\ - \x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nam\ - eB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateVi\ - ewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\ - \x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ + \x12\n\x04data\x18\x07\x20\x01(\x0cR\x04dataB\x12\n\x10one_of_thumbnail\ + \"\xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\ + \x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\ + \x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\ + \x20\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDa\ + taTypeR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\ + \x12\x12\n\x04data\x18\x07\x20\x01(\x0cR\x04data\x12\x1f\n\x0bplugin_typ\ + e\x18\x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\ + \x18\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\ + \x18\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\ + \x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\ + \x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\ + \x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of\ + _nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10Upda\ + teViewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\ + \n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\ mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\ l*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01\ diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index b66f778a71..56e09c54e4 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -24,7 +24,7 @@ message CreateViewPayload { oneof one_of_thumbnail { string thumbnail = 4; }; ViewDataType data_type = 5; int32 plugin_type = 6; - string data = 7; + bytes data = 7; } message CreateViewParams { string belong_to_id = 1; @@ -33,7 +33,7 @@ message CreateViewParams { string thumbnail = 4; ViewDataType data_type = 5; string view_id = 6; - string data = 7; + bytes data = 7; int32 plugin_type = 8; } message ViewId { diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index c7cd8338c8..f8c762345d 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,7 +1,8 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use strum_macros::{Display, EnumIter, EnumString}; +use strum::{EnumCount, IntoEnumIterator}; +use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_FIELD_WIDTH: i32 = 150; @@ -139,7 +140,9 @@ pub struct FieldChangeset { pub type_options: Option, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] +#[derive( + Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize, +)] pub enum FieldType { RichText = 0, Number = 1, @@ -312,3 +315,31 @@ impl std::convert::From for RowMetaChangeset { } } } + +#[derive(Clone, ProtoBuf)] +pub struct BuildGridContext { + #[pb(index = 1)] + pub field_metas: Vec, + + #[pb(index = 2)] + pub grid_block: GridBlock, + + #[pb(index = 3)] + pub grid_block_meta: GridBlockMeta, +} + +impl std::default::Default for BuildGridContext { + fn default() -> Self { + let grid_block = GridBlock::new(); + let grid_block_meta = GridBlockMeta { + block_id: grid_block.id.clone(), + rows: vec![], + }; + + Self { + field_metas: vec![], + grid_block, + grid_block_meta, + } + } +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index bd01ee6cf6..9a90b67f81 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -3073,6 +3073,286 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { } } +#[derive(PartialEq,Clone,Default)] +pub struct BuildGridContext { + // message fields + pub field_metas: ::protobuf::RepeatedField, + pub grid_block: ::protobuf::SingularPtrField, + pub grid_block_meta: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a BuildGridContext { + fn default() -> &'a BuildGridContext { + ::default_instance() + } +} + +impl BuildGridContext { + pub fn new() -> BuildGridContext { + ::std::default::Default::default() + } + + // repeated .FieldMeta field_metas = 1; + + + pub fn get_field_metas(&self) -> &[FieldMeta] { + &self.field_metas + } + pub fn clear_field_metas(&mut self) { + self.field_metas.clear(); + } + + // Param is passed by value, moved + pub fn set_field_metas(&mut self, v: ::protobuf::RepeatedField) { + self.field_metas = v; + } + + // Mutable pointer to the field. + pub fn mut_field_metas(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.field_metas + } + + // Take field + pub fn take_field_metas(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) + } + + // .GridBlock grid_block = 2; + + + pub fn get_grid_block(&self) -> &GridBlock { + self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_grid_block(&mut self) { + self.grid_block.clear(); + } + + pub fn has_grid_block(&self) -> bool { + self.grid_block.is_some() + } + + // Param is passed by value, moved + pub fn set_grid_block(&mut self, v: GridBlock) { + self.grid_block = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_block(&mut self) -> &mut GridBlock { + if self.grid_block.is_none() { + self.grid_block.set_default(); + } + self.grid_block.as_mut().unwrap() + } + + // Take field + pub fn take_grid_block(&mut self) -> GridBlock { + self.grid_block.take().unwrap_or_else(|| GridBlock::new()) + } + + // .GridBlockMeta grid_block_meta = 3; + + + pub fn get_grid_block_meta(&self) -> &GridBlockMeta { + self.grid_block_meta.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_grid_block_meta(&mut self) { + self.grid_block_meta.clear(); + } + + pub fn has_grid_block_meta(&self) -> bool { + self.grid_block_meta.is_some() + } + + // Param is passed by value, moved + pub fn set_grid_block_meta(&mut self, v: GridBlockMeta) { + self.grid_block_meta = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_block_meta(&mut self) -> &mut GridBlockMeta { + if self.grid_block_meta.is_none() { + self.grid_block_meta.set_default(); + } + self.grid_block_meta.as_mut().unwrap() + } + + // Take field + pub fn take_grid_block_meta(&mut self) -> GridBlockMeta { + self.grid_block_meta.take().unwrap_or_else(|| GridBlockMeta::new()) + } +} + +impl ::protobuf::Message for BuildGridContext { + fn is_initialized(&self) -> bool { + for v in &self.field_metas { + if !v.is_initialized() { + return false; + } + }; + for v in &self.grid_block { + if !v.is_initialized() { + return false; + } + }; + for v in &self.grid_block_meta { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.field_metas { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(ref v) = self.grid_block.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.grid_block_meta.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.field_metas { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(ref v) = self.grid_block.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.grid_block_meta.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> BuildGridContext { + BuildGridContext::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field_metas", + |m: &BuildGridContext| { &m.field_metas }, + |m: &mut BuildGridContext| { &mut m.field_metas }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_block", + |m: &BuildGridContext| { &m.grid_block }, + |m: &mut BuildGridContext| { &mut m.grid_block }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_block_meta", + |m: &BuildGridContext| { &m.grid_block_meta }, + |m: &mut BuildGridContext| { &mut m.grid_block_meta }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "BuildGridContext", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static BuildGridContext { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(BuildGridContext::new) + } +} + +impl ::protobuf::Clear for BuildGridContext { + fn clear(&mut self) { + self.field_metas.clear(); + self.grid_block.clear(); + self.grid_block_meta.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for BuildGridContext { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for BuildGridContext { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3178,10 +3458,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\ ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\ (\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\ - \x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Nu\ - mber\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ - \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ - proto3\ + \x0bone_of_data\"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\ + \x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\ + \x02\x20\x01(\x0b2\n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\ + \x03\x20\x01(\x0b2\x0e.GridBlockMetaR\rgridBlockMeta*d\n\tFieldType\x12\ + \x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\ + \x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\ + \x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 32fc3896ac..12447f6e8f 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -60,6 +60,11 @@ message CellMetaChangeset { string field_id = 2; oneof one_of_data { string data = 3; }; } +message BuildGridContext { + repeated FieldMeta field_metas = 1; + GridBlock grid_block = 2; + GridBlockMeta grid_block_meta = 3; +} enum FieldType { RichText = 0; Number = 1; diff --git a/shared-lib/lib-ot/src/core/delta/delta.rs b/shared-lib/lib-ot/src/core/delta/delta.rs index ac4fcbbef5..29fd424dcb 100644 --- a/shared-lib/lib-ot/src/core/delta/delta.rs +++ b/shared-lib/lib-ot/src/core/delta/delta.rs @@ -529,7 +529,7 @@ where self.apply("") } - pub fn to_bytes(&self) -> Bytes { + pub fn to_delta_bytes(&self) -> Bytes { let json = self.to_delta_str(); Bytes::from(json.into_bytes()) } From b3ed254cafe681c466e19ac45c46b114a1e3055a Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 10:02:37 +0800 Subject: [PATCH 041/179] chore: add more test and fix warnings --- frontend/rust-lib/flowy-error/src/errors.rs | 2 + .../flowy-folder/tests/workspace/script.rs | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 6 +- frontend/rust-lib/flowy-grid/src/manager.rs | 6 +- .../src/services/block_meta_editor.rs | 4 +- .../cell/description/date_description.rs | 11 +- .../cell/description/number_description.rs | 21 ++- .../cell/description/selection_description.rs | 49 +++-- .../cell/description/text_description.rs | 7 +- .../flowy-grid/src/services/grid_editor.rs | 27 ++- .../src/services/row/row_builder.rs | 31 +++- .../flowy-grid/tests/grid/grid_test.rs | 168 ++++++++++++++++-- .../rust-lib/flowy-grid/tests/grid/script.rs | 18 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 2 +- .../src/client_grid/block_pad.rs | 2 +- .../src/client_grid/grid_builder.rs | 14 +- .../{grid_pad.rs => grid_meta_pad.rs} | 18 +- .../src/client_grid/mod.rs | 4 +- shared-lib/flowy-error-code/src/code.rs | 4 + .../src/protobuf/model/code.rs | 13 +- .../src/protobuf/proto/code.proto | 2 + .../src/entities/view.rs | 2 +- .../src/entities/meta.rs | 6 +- shared-lib/lib-infra/src/future.rs | 31 ---- 24 files changed, 318 insertions(+), 132 deletions(-) rename shared-lib/flowy-collaboration/src/client_grid/{grid_pad.rs => grid_meta_pad.rs} (95%) diff --git a/frontend/rust-lib/flowy-error/src/errors.rs b/frontend/rust-lib/flowy-error/src/errors.rs index 956df16fa5..cd890fd02e 100644 --- a/frontend/rust-lib/flowy-error/src/errors.rs +++ b/frontend/rust-lib/flowy-error/src/errors.rs @@ -64,6 +64,8 @@ impl FlowyError { static_flowy_error!(name_empty, ErrorCode::UserNameIsEmpty); static_flowy_error!(user_id, ErrorCode::UserIdInvalid); static_flowy_error!(user_not_exist, ErrorCode::UserNotExist); + static_flowy_error!(text_too_long, ErrorCode::TextTooLong); + static_flowy_error!(invalid_data, ErrorCode::InvalidData); } impl std::convert::From for FlowyError { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 3cb65a414c..e476c36f2d 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -351,7 +351,7 @@ pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &st thumbnail: None, data_type, plugin_type: 0, - data: "".to_string(), + data: vec![], }; let view = FolderEventBuilder::new(sdk.clone()) .event(CreateView) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 5028a40407..28e25854d0 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -36,11 +36,7 @@ pub(crate) async fn get_fields_handler( let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?; - let repeated_field: RepeatedField = field_metas - .into_iter() - .map(|field_meta| Field::from(field_meta)) - .collect::>() - .into(); + let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 28a246bd75..fde6d136f2 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -111,8 +111,7 @@ impl GridManager { ) -> Result, FlowyError> { let user = self.grid_user.clone(); let rev_manager = self.make_grid_rev_manager(grid_id, pool.clone())?; - let kv_persistence = self.get_kv_persistence()?; - let grid_editor = ClientGridEditor::new(grid_id, user, rev_manager, kv_persistence).await?; + let grid_editor = ClientGridEditor::new(grid_id, user, rev_manager).await?; Ok(grid_editor) } @@ -137,6 +136,7 @@ impl GridManager { Ok(rev_manager) } + #[allow(dead_code)] fn get_kv_persistence(&self) -> FlowyResult> { let read_guard = self.kv_persistence.read(); if read_guard.is_some() { @@ -198,7 +198,7 @@ pub async fn make_grid_view_data( let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, &block_id, block_meta_delta_data).into(); + Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into(); let _ = grid_manager .create_grid_block_meta(&block_id, repeated_revision) .await?; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index fb72f8c34d..f0d0b8e475 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -139,7 +139,7 @@ impl GridBlockMetaEditorManager { for grid_block in grid_blocks { let editor = self.get_editor(&grid_block.id).await?; let row_metas = editor.get_row_metas(None).await?; - let block_row_orders = row_metas.iter().map(|row_meta| RowOrder::from(row_meta)); + let block_row_orders = row_metas.iter().map(RowOrder::from); row_orders.extend(block_row_orders); } Ok(row_orders) @@ -257,7 +257,7 @@ impl ClientGridBlockMetaEditor { .await .get_rows(None)? .iter() - .map(|row_meta| RowOrder::from(row_meta)) + .map(RowOrder::from) .collect::>(); Ok(row_orders) } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 1b057b5314..30af0fb160 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -53,14 +53,11 @@ impl CellDataSerde for DateDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - let timestamp = match data.parse::() { - Ok(timestamp) => timestamp, - Err(e) => { - tracing::error!("Parse {} to i64 failed: {}", data, e); - chrono::Utc::now().timestamp() - } + if let Err(e) = data.parse::() { + tracing::error!("Parse {} to i64 failed: {}", data, e); + return Err(FlowyError::internal().context(e)); }; - Ok(format!("{}", timestamp)) + Ok(data.to_owned()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs index a4a3c08d90..c3468786df 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -93,7 +93,7 @@ impl NumberDescription { } fn decimal_from_str(&self, s: &str) -> Decimal { - let mut decimal = Decimal::from_str(s).unwrap_or(Decimal::zero()); + let mut decimal = Decimal::from_str(s).unwrap_or_else(|_| Decimal::zero()); match decimal.set_scale(self.scale) { Ok(_) => {} Err(e) => { @@ -130,7 +130,12 @@ impl CellDataSerde for NumberDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(self.strip_symbol(data)) + let data = self.strip_symbol(data); + + if !data.chars().all(char::is_numeric) { + return Err(FlowyError::invalid_data().context("Should only contain numbers")); + } + Ok(data) } } @@ -188,8 +193,10 @@ mod tests { #[test] fn number_description_scale_test() { - let mut description = NumberDescription::default(); - description.scale = 1; + let mut description = NumberDescription { + scale: 1, + ..Default::default() + }; for format in NumberFormat::iter() { description.format = format; @@ -224,8 +231,10 @@ mod tests { #[test] fn number_description_sign_test() { - let mut description = NumberDescription::default(); - description.sign_positive = false; + let mut description = NumberDescription { + sign_positive: false, + ..Default::default() + }; for format in NumberFormat::iter() { description.format = format; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 2f772c3c5d..0115e390dd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -2,9 +2,13 @@ use crate::impl_from_and_to_type_option; use crate::services::row::CellDataSerde; use crate::services::util::*; use flowy_derive::ProtoBuf; -use flowy_error::FlowyError; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +pub const SELECTION_IDS_SEPARATOR: &str = ","; // Single select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] @@ -23,7 +27,7 @@ impl CellDataSerde for SingleSelectDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(select_option_id_from_data(data.to_owned(), true)) + single_select_option_id_from_data(data.to_owned()) } } @@ -43,20 +47,45 @@ impl CellDataSerde for MultiSelectDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(select_option_id_from_data(data.to_owned(), false)) + multi_select_option_id_from_data(data.to_owned()) } } -fn select_option_id_from_data(data: String, is_single_select: bool) -> String { - if !is_single_select { - return data; - } - let select_option_ids = data.split(',').collect::>(); +fn single_select_option_id_from_data(data: String) -> FlowyResult { + let select_option_ids = select_option_ids(data)?; if select_option_ids.is_empty() { - return "".to_owned(); + return Ok("".to_owned()); } - select_option_ids.split_first().unwrap().0.to_string() + Ok(select_option_ids.split_first().unwrap().0.to_string()) +} + +fn multi_select_option_id_from_data(data: String) -> FlowyResult { + let select_option_ids = select_option_ids(data)?; + Ok(select_option_ids.join(SELECTION_IDS_SEPARATOR)) +} + +fn select_option_ids(mut data: String) -> FlowyResult> { + data.retain(|c| !c.is_whitespace()); + let select_option_ids = data.split(SELECTION_IDS_SEPARATOR).collect::>(); + if select_option_ids + .par_iter() + .find_first(|option_id| match Uuid::parse_str(option_id) { + Ok(_) => false, + Err(e) => { + tracing::error!("{}", e); + true + } + }) + .is_some() + { + let msg = format!( + "Invalid selection id string: {}. It should consist of the uuid string and separated by comma", + data + ); + return Err(FlowyError::internal().context(msg)); + } + Ok(select_option_ids.iter().map(|id| id.to_string()).collect::>()) } #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs index 1f71244519..539b82402c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -19,6 +19,11 @@ impl CellDataSerde for RichTextDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(data.to_owned()) + let data = data.to_owned(); + if data.len() > 10000 { + Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) + } else { + Ok(data) + } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 86c7a8fc0e..9436b62e6f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,19 +1,19 @@ use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use bytes::Bytes; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, + CellMetaChangeset, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; use crate::services::row::{ - make_row_by_row_id, make_rows, row_meta_from_context, CreateRowContext, CreateRowContextBuilder, + make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, CreateRowContext, + CreateRowContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -27,7 +27,6 @@ pub struct ClientGridEditor { grid_meta_pad: Arc>, rev_manager: Arc, block_meta_manager: Arc, - kv_persistence: Arc, } impl ClientGridEditor { @@ -35,7 +34,6 @@ impl ClientGridEditor { grid_id: &str, user: Arc, mut rev_manager: RevisionManager, - kv_persistence: Arc, ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); @@ -52,7 +50,6 @@ impl ClientGridEditor { grid_meta_pad, rev_manager, block_meta_manager, - kv_persistence, })) } @@ -88,7 +85,8 @@ impl ClientGridEditor { pub async fn create_row(&self) -> FlowyResult<()> { let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; - let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&field_metas).build()); + let create_row_ctx = CreateRowContextBuilder::new(&field_metas).build(); + let row = row_meta_from_context(&block_id, create_row_ctx); let row_count = self.block_meta_manager.create_row(row).await?; let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; @@ -98,12 +96,11 @@ impl ClientGridEditor { pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { let block_id = self.last_block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); - for ctx in contexts { let row_meta = row_meta_from_context(&block_id, ctx); rows_by_block_id .entry(block_id.clone()) - .or_insert(Vec::new()) + .or_insert_with(Vec::new) .push(row_meta); } let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; @@ -118,6 +115,18 @@ impl ClientGridEditor { } pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + if let Some(cell_data) = changeset.data.as_ref() { + match self.grid_meta_pad.read().await.get_field(&changeset.field_id) { + None => { + return Err(FlowyError::internal() + .context(format!("Can not find the field with id: {}", &changeset.field_id))); + } + Some(field_meta) => { + let _ = serialize_cell_data(cell_data, field_meta)?; + } + } + } + let row_changeset: RowMetaChangeset = changeset.into(); self.update_row(row_changeset).await } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 6bc231293a..676411e8c7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,28 +1,43 @@ +use crate::services::row::serialize_cell_data; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; pub struct CreateRowContextBuilder<'a> { - #[allow(dead_code)] - fields: &'a [FieldMeta], + field_meta_map: HashMap<&'a String, &'a FieldMeta>, ctx: CreateRowContext, } impl<'a> CreateRowContextBuilder<'a> { pub fn new(fields: &'a [FieldMeta]) -> Self { + let field_meta_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + let ctx = CreateRowContext { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, }; - Self { fields, ctx } + + Self { field_meta_map, ctx } } - #[allow(dead_code)] - pub fn add_cell(mut self, field_id: &str, data: String) -> Self { - let cell = CellMeta::new(field_id, data); - self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); - self + pub fn add_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> { + match self.field_meta_map.get(&field_id.to_owned()) { + None => { + let msg = format!("Invalid field_id: {}", field_id); + Err(FlowyError::internal().context(msg)) + } + Some(field_meta) => { + let data = serialize_cell_data(&data, field_meta)?; + let cell = CellMeta::new(field_id, data); + self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); + Ok(()) + } + } } #[allow(dead_code)] diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 30469d406f..acb8e27c39 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,8 +1,11 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; +use chrono::NaiveDateTime; use flowy_grid::services::cell::*; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; -use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; +use flowy_grid_data_model::entities::{ + CellMetaChangeset, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset, +}; #[tokio::test] async fn grid_create_field() { @@ -237,29 +240,28 @@ async fn grid_delete_row() { } #[tokio::test] -async fn grid_update_cell() { +async fn grid_row_add_cells_test() { let mut test = GridEditorTest::new().await; let mut builder = CreateRowContextBuilder::new(&test.field_metas); for field in &test.field_metas { match field.field_type { FieldType::RichText => { let data = serialize_cell_data("hello world", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::Number => { let data = serialize_cell_data("¥18,443", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::DateTime => { let data = serialize_cell_data("1647251762", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::SingleSelect => { let description = SingleSelectDescription::from(field); let options = description.options.first().unwrap(); - let data = description.serialize_cell_data(&options.id).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { let description = MultiSelectDescription::from(field); @@ -268,17 +270,161 @@ async fn grid_update_cell() { .iter() .map(|option| option.id.clone()) .collect::>() - .join(","); + .join(SELECTION_IDS_SEPARATOR); let data = description.serialize_cell_data(&options).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::Checkbox => { let data = serialize_cell_data("false", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } } } let context = builder.build(); - let scripts = vec![AssertRowCount(3), CreateRow { context }, AssertGridMetaPad]; + let scripts = vec![CreateRow { context }, AssertGridMetaPad]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_row_add_selection_cell_test() { + let mut test = GridEditorTest::new().await; + let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let uuid = uuid::Uuid::new_v4().to_string(); + let mut single_select_field_id = "".to_string(); + let mut multi_select_field_id = "".to_string(); + for field in &test.field_metas { + match field.field_type { + FieldType::SingleSelect => { + single_select_field_id = field.id.clone(); + // The element must be parsed as uuid + assert!(builder.add_cell(&field.id, "data".to_owned()).is_err()); + // // The data should not be empty + assert!(builder.add_cell(&field.id, "".to_owned()).is_err()); + // The element must be parsed as uuid + assert!(builder.add_cell(&field.id, "1,2,3".to_owned()).is_err(),); + // The separator must be comma + assert!(builder.add_cell(&field.id, format!("{}. {}", &uuid, &uuid),).is_err()); + // + + assert!(builder.add_cell(&field.id, uuid.clone()).is_ok()); + assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok()); + } + FieldType::MultiSelect => { + multi_select_field_id = field.id.clone(); + assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok()); + } + _ => {} + } + } + let context = builder.build(); + assert_eq!( + &context + .cell_by_field_id + .get(&single_select_field_id) + .as_ref() + .unwrap() + .data, + &uuid + ); + assert_eq!( + context + .cell_by_field_id + .get(&multi_select_field_id) + .as_ref() + .unwrap() + .data, + format!("{},{}", &uuid, &uuid) + ); + + let scripts = vec![CreateRow { context }]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_row_add_date_cell_test() { + let mut test = GridEditorTest::new().await; + let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut date_field = None; + let timestamp = 1647390674; + for field in &test.field_metas { + if field.field_type == FieldType::DateTime { + date_field = Some(field.clone()); + NaiveDateTime::from_timestamp(123, 0); + // The data should not be empty + assert!(builder.add_cell(&field.id, "".to_owned()).is_err()); + + assert!(builder.add_cell(&field.id, "123".to_owned()).is_ok()); + assert!(builder.add_cell(&field.id, format!("{}", timestamp)).is_ok()); + } + } + let context = builder.build(); + let date_field = date_field.unwrap(); + let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); + assert_eq!( + deserialize_cell_data(cell_data.data.clone(), &date_field).unwrap(), + "2022/03/16 08:31", + ); + let scripts = vec![CreateRow { context }]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_cell_update() { + let mut test = GridEditorTest::new().await; + let field_metas = &test.field_metas; + let row_metas = &test.row_metas; + assert_eq!(row_metas.len(), 3); + + let mut scripts = vec![]; + for (index, row_meta) in row_metas.iter().enumerate() { + for field_meta in field_metas { + if index == 0 { + let data = match field_meta.field_type { + FieldType::RichText => "".to_string(), + FieldType::Number => "123".to_string(), + FieldType::DateTime => "123".to_string(), + FieldType::SingleSelect => { + let description = SingleSelectDescription::from(field_meta); + description.options.first().unwrap().id.clone() + } + FieldType::MultiSelect => { + let description = MultiSelectDescription::from(field_meta); + description.options.first().unwrap().id.clone() + } + FieldType::Checkbox => "1".to_string(), + }; + + scripts.push(UpdateCell { + changeset: CellMetaChangeset { + row_id: row_meta.id.clone(), + field_id: field_meta.id.clone(), + data: Some(data), + }, + is_err: false, + }); + } + + if index == 1 { + let (data, is_err) = match field_meta.field_type { + FieldType::RichText => ("1".to_string().repeat(10001), true), + FieldType::Number => ("abc".to_string(), true), + FieldType::DateTime => ("abc".to_string(), true), + FieldType::SingleSelect => ("abc".to_string(), true), + FieldType::MultiSelect => ("abc".to_string(), true), + FieldType::Checkbox => ("2".to_string(), false), + }; + + scripts.push(UpdateCell { + changeset: CellMetaChangeset { + row_id: row_meta.id.clone(), + field_id: field_meta.id.clone(), + data: Some(data), + }, + is_err, + }); + } + } + } + test.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index c49bf82a03..2c784153be 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,6 @@ use bytes::Bytes; use flowy_collaboration::client_grid::GridBuilder; -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; -use flowy_error::FlowyResult; -use flowy_grid::manager::{make_grid_view_data, GridManager}; + use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; @@ -16,7 +14,7 @@ use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; use std::time::Duration; -use strum::{EnumCount, IntoEnumIterator}; +use strum::EnumCount; use tokio::time::sleep; pub enum EditorScript { @@ -65,6 +63,7 @@ pub enum EditorScript { }, UpdateCell { changeset: CellMetaChangeset, + is_err: bool, }, AssertRowCount(usize), // AssertRowEqual{ row_index: usize, row: RowMeta}, @@ -199,9 +198,14 @@ impl GridEditorTest { assert_eq!(row.height, height); } } - EditorScript::UpdateCell { changeset } => { - self.editor.update_cell(changeset).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + EditorScript::UpdateCell { changeset, is_err } => { + let result = self.editor.update_cell(changeset).await; + if is_err { + assert!(result.is_err()) + } else { + let _ = result.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + } } EditorScript::AssertRowCount(count) => { assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 89346eaf35..6ed3df3207 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -4,7 +4,7 @@ use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; -use flowy_folder::errors::FlowyResult; + use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; use flowy_folder::prelude::ViewDataType; use flowy_folder::{ diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index fafa2d45ce..840e4c28af 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -52,7 +52,7 @@ impl GridBlockMetaPad { pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { match row_ids { - None => Ok(self.rows.iter().map(|row| row.clone()).collect::>()), + None => Ok(self.rows.to_vec()), Some(row_ids) => { let row_map = self .rows diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 42faa4abda..a6be909ef6 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,19 +1,11 @@ -use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, RowMeta}; +#[derive(Default)] pub struct GridBuilder { build_context: BuildGridContext, } -impl std::default::Default for GridBuilder { - fn default() -> Self { - Self { - build_context: Default::default(), - } - } -} - impl GridBuilder { pub fn add_field(mut self, field: FieldMeta) -> Self { self.build_context.field_metas.push(field); @@ -63,7 +55,7 @@ mod tests { .build(); let grid_meta = GridMeta { - grid_id: grid_id.clone(), + grid_id, fields: build_context.field_metas, blocks: vec![build_context.grid_block], }; diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs similarity index 95% rename from shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs rename to shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index bcae5144a8..e836034fae 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -58,19 +58,15 @@ impl GridMetaPad { } pub fn contain_field(&self, field_id: &str) -> bool { - self.grid_meta - .fields - .iter() - .find(|field| &field.id == field_id) - .is_some() + self.grid_meta.fields.iter().any(|field| field.id == field_id) + } + + pub fn get_field(&self, field_id: &str) -> Option<&FieldMeta> { + self.grid_meta.fields.iter().find(|field| field.id == field_id) } pub fn get_field_orders(&self) -> Vec { - self.grid_meta - .fields - .iter() - .map(|field_meta| FieldOrder::from(field_meta)) - .collect() + self.grid_meta.fields.iter().map(FieldOrder::from).collect() } pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { @@ -154,7 +150,7 @@ impl GridMetaPad { if last_block.start_row_index > block.start_row_index && last_block.len() > block.start_row_index { - let msg = format!("GridBlock's start_row_index should be greater than the last_block's start_row_index and its len"); + let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string(); return Err(CollaborateError::internal().context(msg)) } grid.blocks.push(block); diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index 5fbaa170b4..9dcb155557 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,7 +1,7 @@ mod block_pad; mod grid_builder; -mod grid_pad; +mod grid_meta_pad; pub use block_pad::*; pub use grid_builder::*; -pub use grid_pad::*; +pub use grid_meta_pad::*; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index c47d4fd8d4..166202bd5b 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -83,6 +83,10 @@ pub enum ErrorCode { UserIdInvalid = 311, #[display(fmt = "User not exist")] UserNotExist = 312, + #[display(fmt = "Text is too long")] + TextTooLong = 400, + #[display(fmt = "Invalid data")] + InvalidData = 401, } impl ErrorCode { diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index f70c1eb49d..769c059eb2 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -55,6 +55,8 @@ pub enum ErrorCode { UserNameIsEmpty = 310, UserIdInvalid = 311, UserNotExist = 312, + TextTooLong = 400, + InvalidData = 401, } impl ::protobuf::ProtobufEnum for ErrorCode { @@ -94,6 +96,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 310 => ::std::option::Option::Some(ErrorCode::UserNameIsEmpty), 311 => ::std::option::Option::Some(ErrorCode::UserIdInvalid), 312 => ::std::option::Option::Some(ErrorCode::UserNotExist), + 400 => ::std::option::Option::Some(ErrorCode::TextTooLong), + 401 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None } } @@ -130,6 +134,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::UserNameIsEmpty, ErrorCode::UserIdInvalid, ErrorCode::UserNotExist, + ErrorCode::TextTooLong, + ErrorCode::InvalidData, ]; values } @@ -158,7 +164,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xc4\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xe8\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x18\n\x14WorkspaceNameInvalid\x10d\x12\x16\n\x12WorkspaceIdInvalid\x10e\ \x12\x18\n\x14AppColorStyleInvalid\x10f\x12\x18\n\x14WorkspaceDescTooLon\ @@ -174,8 +180,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ rmatInvalid\x10\xb2\x02\x12\x15\n\x10PasswordNotMatch\x10\xb3\x02\x12\ \x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\n\"UserNameContainForbiddenCh\ aracters\x10\xb5\x02\x12\x14\n\x0fUserNameIsEmpty\x10\xb6\x02\x12\x12\n\ - \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02b\x06pr\ - oto3\ + \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02\x12\ + \x10\n\x0bTextTooLong\x10\x90\x03\x12\x10\n\x0bInvalidData\x10\x91\x03b\ + \x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index ed12d58848..4bf692b8ff 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -31,4 +31,6 @@ enum ErrorCode { UserNameIsEmpty = 310; UserIdInvalid = 311; UserNotExist = 312; + TextTooLong = 400; + InvalidData = 401; } diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index ac346188ce..3b98e3f64c 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -4,7 +4,7 @@ use crate::{ impl_def_and_def_mut, parser::{ app::AppIdentify, - view::{ViewDesc, ViewExtensionData, ViewIdentify, ViewName, ViewThumbnail}, + view::{ViewDesc, ViewIdentify, ViewName, ViewThumbnail}, }, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index f8c762345d..d70d17e0e9 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,7 +1,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use strum::{EnumCount, IntoEnumIterator}; + use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; @@ -35,6 +35,10 @@ impl GridBlock { pub fn len(&self) -> i32 { self.start_row_index + self.row_count } + + pub fn is_empty(&self) -> bool { + self.row_count == 0 + } } impl GridBlock { diff --git a/shared-lib/lib-infra/src/future.rs b/shared-lib/lib-infra/src/future.rs index 9a0b6550dd..9077dd18b7 100644 --- a/shared-lib/lib-infra/src/future.rs +++ b/shared-lib/lib-infra/src/future.rs @@ -65,34 +65,3 @@ where } pub type BoxResultFuture<'a, T, E> = BoxFuture<'a, Result>; - -#[pin_project] -pub struct FutureResultSend { - #[pin] - pub fut: Pin> + Send>>, -} - -impl FutureResultSend { - pub fn new(f: F) -> Self - where - F: Future> + Send + 'static, - { - Self { - fut: Box::pin(async { f.await }), - } - } -} - -impl Future for FutureResultSend -where - T: Send, - E: Debug, -{ - type Output = Result; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.as_mut().project(); - let result = ready!(this.fut.poll(cx)); - Poll::Ready(result) - } -} From 8c148e3b67bdeea448dc0b7c5068e2609bd9092d Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 16:10:35 +0800 Subject: [PATCH 042/179] chore: save text cell data & insert row --- .../lib/startup/home_deps_resolver.dart | 43 ++- .../grid/cell_bloc/cell_service.dart | 30 ++- .../grid/cell_bloc/checkbox_cell_bloc.dart | 6 +- .../grid/cell_bloc/date_cell_bloc.dart | 6 +- .../grid/cell_bloc/number_cell_bloc.dart | 6 +- .../grid/cell_bloc/selection_cell_bloc.dart | 6 +- .../grid/cell_bloc/text_cell_bloc.dart | 11 +- .../lib/workspace/application/grid/data.dart | 5 + .../workspace/application/grid/grid_bloc.dart | 7 +- .../application/grid/grid_listener.dart | 0 .../application/grid/grid_service.dart | 6 +- .../workspace/application/grid/row_bloc.dart | 6 +- .../application/grid/row_service.dart | 13 +- .../src/widgets/content/cell_builder.dart | 18 +- .../src/widgets/content/checkbox_cell.dart | 12 +- .../grid/src/widgets/content/date_cell.dart | 12 +- .../grid/src/widgets/content/grid_row.dart | 19 +- .../grid/src/widgets/content/number_cell.dart | 10 +- .../src/widgets/content/selection_cell.dart | 21 +- .../grid/src/widgets/content/text_cell.dart | 13 +- .../grid/src/widgets/footer/grid_footer.dart | 10 +- .../dart_event/flowy-grid/dart_event.dart | 8 +- .../flowy-error-code/code.pbenum.dart | 4 + .../flowy-error-code/code.pbjson.dart | 4 +- .../flowy-grid-data-model/grid.pb.dart | 74 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 14 + .../flowy-grid-data-model/meta.pb.dart | 48 ++-- .../flowy-grid-data-model/meta.pbjson.dart | 9 +- .../rust-lib/flowy-grid/src/event_handler.rs | 25 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 4 +- .../src/services/block_meta_editor.rs | 10 +- .../flowy-grid/src/services/grid_editor.rs | 25 +- .../src/services/row/row_builder.rs | 14 +- .../flowy-grid/src/services/row/row_loader.rs | 1 + frontend/rust-lib/flowy-grid/src/util.rs | 3 +- .../flowy-grid/tests/grid/grid_test.rs | 21 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- .../src/client_grid/block_pad.rs | 96 ++++++- .../src/entities/grid.rs | 9 + .../src/entities/meta.rs | 7 +- .../src/protobuf/model/grid.rs | 254 +++++++++++++++++- .../src/protobuf/model/meta.rs | 85 ++++-- .../src/protobuf/proto/grid.proto | 4 + .../src/protobuf/proto/meta.proto | 7 +- 44 files changed, 759 insertions(+), 231 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 5b91d8a545..cbb359f09d 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -98,8 +98,7 @@ class HomeDepsResolver { getIt.registerFactoryParam( (data, _) => RowBloc( - data: data, - service: RowService(), + service: RowService(data), ), ); @@ -110,43 +109,33 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam( - (field, cell) => TextCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => TextCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => SelectionCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => SelectionCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => NumberCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => NumberCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => DateCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => DateCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => CheckboxCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => CheckboxCellBloc( + service: CellService(context), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index c5098155cb..456615220d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1 +1,29 @@ -class CellService {} +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; + +class CellService { + final CellContext context; + + CellService(this.context); + + Future> updateCell({required String data}) { + final payload = CellMetaChangeset.create() + ..gridId = context.gridId + ..fieldId = context.field.id + ..rowId = context.rowId + ..data = data; + return GridEventUpdateCell(payload).send(); + } +} + +class CellContext { + final String gridId; + final String rowId; + final Field field; + final Cell? cell; + + CellContext({required this.rowId, required this.gridId, required this.field, required this.cell}); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 8f0de7fb32..ab844448dc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; CheckboxCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(CheckboxCellState.initial(cell)) { + }) : super(CheckboxCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index c8b5e97f2d..dcb0461165 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; DateCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(DateCellState.initial(cell)) { + }) : super(DateCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index b216550a81..caa91fa408 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'number_cell_bloc.freezed.dart'; class NumberCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; NumberCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(NumberCellState.initial(cell)) { + }) : super(NumberCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 5e7a6e8e22..7f21a84fff 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; SelectionCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(SelectionCellState.initial(cell)) { + }) : super(SelectionCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index cce4ff9224..80bc722be7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -1,4 +1,3 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -7,20 +6,18 @@ import 'cell_service.dart'; part 'text_cell_bloc.freezed.dart'; class TextCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; TextCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(TextCellState.initial(cell?.content ?? "")) { + }) : super(TextCellState.initial(service.context.cell?.content ?? "")) { on( (event, emit) async { await event.map( initial: (_InitialCell value) async {}, - updateText: (_UpdateText value) {}, + updateText: (_UpdateText value) { + service.updateCell(data: value.text); + }, ); }, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index c32f87f1a2..77cb1d9e6d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -2,10 +2,12 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:equatable/equatable.dart'; class GridInfo { + final String gridId; List rows; List fields; GridInfo({ + required this.gridId, required this.rows, required this.fields, }); @@ -13,6 +15,7 @@ class GridInfo { GridRowData rowAtIndex(int index) { final row = rows[index]; return GridRowData( + gridId: gridId, row: row, fields: fields, cellMap: row.cellByFieldId, @@ -25,10 +28,12 @@ class GridInfo { } class GridRowData extends Equatable { + final String gridId; final Row row; final List fields; final Map cellMap; const GridRowData({ + required this.gridId, required this.row, required this.fields, required this.cellMap, diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 500db75bf3..b67f119fe3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -70,11 +70,12 @@ class GridBloc extends Bloc { } Future _loadGridInfo(Emitter emit) async { - if (_grid != null && _fields != null) { - final result = await service.getRows(gridId: _grid!.id, rowOrders: _grid!.rowOrders); + final grid = _grid; + if (grid != null && _fields != null) { + final result = await service.getRows(gridId: grid.id, rowOrders: grid.rowOrders); result.fold((repeatedRow) { final rows = repeatedRow.items; - final gridInfo = GridInfo(rows: rows, fields: _fields!); + final gridInfo = GridInfo(gridId: grid.id, rows: rows, fields: _fields!); emit( state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index e519b0a90d..915cc671b6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -12,8 +12,10 @@ class GridService { return GridEventGetGridData(payload).send(); } - Future> createRow({required String gridId}) { - return GridEventCreateRow(GridId(value: gridId)).send(); + Future> createRow({required String gridId, Option? upperRowId}) { + CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; + upperRowId?.fold(() => null, (id) => payload.upperRowId = id); + return GridEventCreateRow(payload).send(); } Future> getRows({required String gridId, required List rowOrders}) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index d2852900d9..1dd20aad9a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -9,12 +9,14 @@ part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { final RowService service; - RowBloc({required GridRowData data, required this.service}) : super(RowState.initial(data)) { + RowBloc({required this.service}) : super(RowState.initial(service.rowData)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async {}, - createRow: (_CreateRow value) {}, + createRow: (_CreateRow value) { + service.createRow(); + }, activeRow: (_ActiveRow value) { emit(state.copyWith(active: true)); }, diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart index ad04b0add2..03d732f862 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -1,10 +1,19 @@ +import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; class RowService { - Future> createRow({required String gridId}) { - return GridEventCreateRow(GridId(value: gridId)).send(); + final GridRowData rowData; + + RowService(this.rowData); + + Future> createRow() { + CreateRowPayload payload = CreateRowPayload.create() + ..gridId = rowData.gridId + ..upperRowId = rowData.row.id; + + return GridEventCreateRow(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 0abfc26047..7b183abbe5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -7,20 +7,20 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(Field field, Cell? cell) { - switch (field.fieldType) { +Widget buildGridCell(CellContext cellContext) { + switch (cellContext.field.fieldType) { case FieldType.Checkbox: - return CheckboxCell(field: field, cell: cell); + return CheckboxCell(cellContext: cellContext); case FieldType.DateTime: - return DateCell(field: field, cell: cell); + return DateCell(cellContext: cellContext); case FieldType.MultiSelect: - return MultiSelectCell(field: field, cell: cell); + return MultiSelectCell(cellContext: cellContext); case FieldType.Number: - return NumberCell(field: field, cell: cell); + return NumberCell(cellContext: cellContext); case FieldType.RichText: - return GridTextCell(field: field, cell: cell); + return GridTextCell(cellContext: cellContext); case FieldType.SingleSelect: - return SingleSelectCell(field: field, cell: cell); + return SingleSelectCell(cellContext: cellContext); default: return const BlankCell(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index d3d2b57735..ec3e51b102 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,16 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const CheckboxCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -23,7 +21,7 @@ class _CheckboxCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -41,7 +39,7 @@ class _CheckboxCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index e1661fdffa..dbe631f2f1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,16 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const DateCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -23,7 +21,7 @@ class _DateCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -41,7 +39,7 @@ class _DateCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index c23bf8f533..c8bd05c3fe 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -54,7 +54,7 @@ class _GridRowWidgetState extends State { @override Future dispose() async { - await _rowBloc.close(); + _rowBloc.close(); super.dispose(); } @@ -66,10 +66,17 @@ class _GridRowWidgetState extends State { key: ValueKey(state.data.row.id), children: state.data.fields.map( (field) { - final cellData = state.data.cellMap[field.id]; + final cell = state.data.cellMap[field.id]; return CellContainer( width: field.width.toDouble(), - child: buildGridCell(field, cellData), + child: buildGridCell( + CellContext( + gridId: state.data.gridId, + rowId: state.data.row.id, + field: field, + cell: cell, + ), + ), ); }, ).toList(), @@ -93,7 +100,7 @@ class LeadingRow extends StatelessWidget { ? Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ - CreateRowButton(), + AppendRowButton(), ], ) : null, @@ -125,8 +132,8 @@ class TrailingRow extends StatelessWidget { } } -class CreateRowButton extends StatelessWidget { - const CreateRowButton({Key? key}) : super(key: key); +class AppendRowButton extends StatelessWidget { + const AppendRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 86b9863019..c624618ec7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,16 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const NumberCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -23,7 +21,7 @@ class _NumberCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 047cff7475..575815013d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -1,15 +1,12 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const SingleSelectCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -22,7 +19,7 @@ class _SingleSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -33,19 +30,17 @@ class _SingleSelectCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } //---------------------------------------------------------------- class MultiSelectCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const MultiSelectCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -58,7 +53,7 @@ class _MultiSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -69,7 +64,7 @@ class _MultiSelectCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 7661ddc22f..c5c330616b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,18 +1,15 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// The interface of base cell. class GridTextCell extends StatefulWidget { - final Field field; - final Cell? cell; - + final CellContext cellContext; const GridTextCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -27,7 +24,7 @@ class _GridTextCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); _controller = TextEditingController(text: _cellBloc.state.content); _focusNode.addListener(_focusChanged); super.initState(); @@ -58,7 +55,7 @@ class _GridTextCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); _focusNode.removeListener(_focusChanged); _focusNode.dispose(); super.dispose(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 5ca3bf0f6b..69e27a0fc4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -20,7 +20,7 @@ class GridFooter extends StatelessWidget { child: Row( children: [ SizedBox(width: GridSize.leadingHeaderPadding), - const SizedBox(width: 120, child: AddRowButton()), + const SizedBox(width: 120, child: _AddRowButton()), ], ), ), @@ -29,8 +29,8 @@ class GridFooter extends StatelessWidget { } } -class AddRowButton extends StatelessWidget { - const AddRowButton({Key? key}) : super(key: key); +class _AddRowButton extends StatelessWidget { + const _AddRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -38,7 +38,7 @@ class AddRowButton extends StatelessWidget { return FlowyButton( text: const FlowyText.medium('New row', fontSize: 12), hoverColor: theme.hover, - onTap: () => context.read().add(const RowEvent.createRow()), + onTap: () => context.read().add(const GridEvent.createRow()), icon: svg("home/add"), ); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index 4aeda8ede9..19c46c8306 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -53,24 +53,24 @@ class GridEventGetFields { } class GridEventCreateRow { - GridId request; + CreateRowPayload request; GridEventCreateRow(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() ..event = GridEvent.CreateRow.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (bytes) => left(unit), + (okBytes) => left(Row.fromBuffer(okBytes)), (errBytes) => right(FlowyError.fromBuffer(errBytes)), )); } } class GridEventUpdateCell { - Cell request; + CellMetaChangeset request; GridEventUpdateCell(this.request); Future> send() { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index dcf1e69936..69efeb81b7 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -40,6 +40,8 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode UserNameIsEmpty = ErrorCode._(310, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameIsEmpty'); static const ErrorCode UserIdInvalid = ErrorCode._(311, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid'); static const ErrorCode UserNotExist = ErrorCode._(312, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist'); + static const ErrorCode TextTooLong = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextTooLong'); + static const ErrorCode InvalidData = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); static const $core.List values = [ Internal, @@ -72,6 +74,8 @@ class ErrorCode extends $pb.ProtobufEnum { UserNameIsEmpty, UserIdInvalid, UserNotExist, + TextTooLong, + InvalidData, ]; static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index c8d7191d54..26a0b31029 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -42,8 +42,10 @@ const ErrorCode$json = const { const {'1': 'UserNameIsEmpty', '2': 310}, const {'1': 'UserIdInvalid', '2': 311}, const {'1': 'UserNotExist', '2': 312}, + const {'1': 'TextTooLong', '2': 400}, + const {'1': 'InvalidData', '2': 401}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgC'); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhAKC0ludmFsaWREYXRhEJED'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 60a0502420..f89285ba92 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -701,6 +701,80 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +enum CreateRowPayload_OneOfUpperRowId { + upperRowId, + notSet +} + +class CreateRowPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CreateRowPayload_OneOfUpperRowId> _CreateRowPayload_OneOfUpperRowIdByTag = { + 2 : CreateRowPayload_OneOfUpperRowId.upperRowId, + 0 : CreateRowPayload_OneOfUpperRowId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateRowPayload', createEmptyInstance: create) + ..oo(0, [2]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'upperRowId') + ..hasRequiredFields = false + ; + + CreateRowPayload._() : super(); + factory CreateRowPayload({ + $core.String? gridId, + $core.String? upperRowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (upperRowId != null) { + _result.upperRowId = upperRowId; + } + return _result; + } + factory CreateRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CreateRowPayload clone() => CreateRowPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateRowPayload copyWith(void Function(CreateRowPayload) updates) => super.copyWith((message) => updates(message as CreateRowPayload)) as CreateRowPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateRowPayload create() => CreateRowPayload._(); + CreateRowPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateRowPayload? _defaultInstance; + + CreateRowPayload_OneOfUpperRowId whichOneOfUpperRowId() => _CreateRowPayload_OneOfUpperRowIdByTag[$_whichOneof(0)]!; + void clearOneOfUpperRowId() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get upperRowId => $_getSZ(1); + @$pb.TagNumber(2) + set upperRowId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasUpperRowId() => $_has(1); + @$pb.TagNumber(2) + void clearUpperRowId() => clearField(2); +} + class QueryFieldPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryFieldPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 0dc1fd25f6..1504b31506 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -151,6 +151,20 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use createRowPayloadDescriptor instead') +const CreateRowPayload$json = const { + '1': 'CreateRowPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'upper_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'upperRowId'}, + ], + '8': const [ + const {'1': 'one_of_upper_row_id'}, + ], +}; + +/// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgx1cHBlcl9yb3dfaWQYAiABKAlIAFIKdXBwZXJSb3dJZEIVChNvbmVfb2ZfdXBwZXJfcm93X2lk'); @$core.Deprecated('Use queryFieldPayloadDescriptor instead') const QueryFieldPayload$json = const { '1': 'QueryFieldPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 0a0837d2df..38adc076a6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -922,24 +922,29 @@ enum CellMetaChangeset_OneOfData { class CellMetaChangeset extends $pb.GeneratedMessage { static const $core.Map<$core.int, CellMetaChangeset_OneOfData> _CellMetaChangeset_OneOfDataByTag = { - 3 : CellMetaChangeset_OneOfData.data, + 4 : CellMetaChangeset_OneOfData.data, 0 : CellMetaChangeset_OneOfData.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMetaChangeset', createEmptyInstance: create) - ..oo(0, [3]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..oo(0, [4]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; CellMetaChangeset._() : super(); factory CellMetaChangeset({ + $core.String? gridId, $core.String? rowId, $core.String? fieldId, $core.String? data, }) { final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } if (rowId != null) { _result.rowId = rowId; } @@ -976,31 +981,40 @@ class CellMetaChangeset extends $pb.GeneratedMessage { void clearOneOfData() => clearField($_whichOneof(0)); @$pb.TagNumber(1) - $core.String get rowId => $_getSZ(0); + $core.String get gridId => $_getSZ(0); @$pb.TagNumber(1) - set rowId($core.String v) { $_setString(0, v); } + set gridId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasRowId() => $_has(0); + $core.bool hasGridId() => $_has(0); @$pb.TagNumber(1) - void clearRowId() => clearField(1); + void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.String get fieldId => $_getSZ(1); + $core.String get rowId => $_getSZ(1); @$pb.TagNumber(2) - set fieldId($core.String v) { $_setString(1, v); } + set rowId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasFieldId() => $_has(1); + $core.bool hasRowId() => $_has(1); @$pb.TagNumber(2) - void clearFieldId() => clearField(2); + void clearRowId() => clearField(2); @$pb.TagNumber(3) - $core.String get data => $_getSZ(2); + $core.String get fieldId => $_getSZ(2); @$pb.TagNumber(3) - set data($core.String v) { $_setString(2, v); } + set fieldId($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasData() => $_has(2); + $core.bool hasFieldId() => $_has(2); @$pb.TagNumber(3) - void clearData() => clearField(3); + void clearFieldId() => clearField(3); + + @$pb.TagNumber(4) + $core.String get data => $_getSZ(3); + @$pb.TagNumber(4) + set data($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasData() => $_has(3); + @$pb.TagNumber(4) + void clearData() => clearField(4); } class BuildGridContext extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 4dceb2116b..7ce08c0a9d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -180,9 +180,10 @@ final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxs const CellMetaChangeset$json = const { '1': 'CellMetaChangeset', '2': const [ - const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'data'}, + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'data'}, ], '8': const [ const {'1': 'one_of_data'}, @@ -190,7 +191,7 @@ const CellMetaChangeset$json = const { }; /// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); +final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIUCgRkYXRhGAQgASgJSABSBGRhdGFCDQoLb25lX29mX2RhdGE='); @$core.Deprecated('Use buildGridContextDescriptor instead') const BuildGridContext$json = const { '1': 'BuildGridContext', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 28e25854d0..e92556b554 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - Cell, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, + CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, + RepeatedRow, Row, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -42,22 +43,22 @@ pub(crate) async fn get_fields_handler( #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_row_handler( - data: Data, + data: Data, manager: AppData>, -) -> Result<(), FlowyError> { - let id: GridId = data.into_inner(); - let editor = manager.get_grid_editor(id.as_ref())?; - let _ = editor.create_row().await?; - Ok(()) +) -> DataResult { + let payload: CreateRowPayload = data.into_inner(); + let editor = manager.get_grid_editor(payload.grid_id.as_ref())?; + let row = editor.create_row(payload.upper_row_id).await?; + data_result(row) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( - data: Data, - _manager: AppData>, + data: Data, + manager: AppData>, ) -> Result<(), FlowyError> { - let _cell: Cell = data.into_inner(); - // let editor = manager.get_grid_editor(id.as_ref())?; - // let _ = editor.create_empty_row().await?; + let changeset: CellMetaChangeset = data.into_inner(); + let editor = manager.get_grid_editor(&changeset.grid_id)?; + let _ = editor.update_cell(changeset).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 773e632191..6adc06e709 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -29,9 +29,9 @@ pub enum GridEvent { #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 2, - #[event(input = "GridId")] + #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 3, - #[event(input = "Cell")] + #[event(input = "CellMetaChangeset")] UpdateCell = 4, } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index f0d0b8e475..0da4b9e609 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -56,10 +56,10 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn create_row(&self, row: RowMeta) -> FlowyResult { + pub(crate) async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); let editor = self.get_editor(&row.block_id).await?; - editor.create_row(row).await + editor.create_row(row, upper_row_id).await } pub(crate) async fn insert_row( @@ -72,7 +72,7 @@ impl GridBlockMetaEditorManager { let mut row_count = 0; for row in rows { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); - row_count = editor.create_row(row).await?; + row_count = editor.create_row(row, None).await?; } changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); } @@ -215,11 +215,11 @@ impl ClientGridBlockMetaEditor { }) } - async fn create_row(&self, row: RowMeta) -> FlowyResult { + async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { let mut row_count = 0; let _ = self .modify(|pad| { - let change = pad.add_row(row)?; + let change = pad.add_row(row, upper_row_id)?; row_count = pad.number_of_rows(); Ok(change) }) diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 9436b62e6f..f6730565ed 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -12,8 +12,7 @@ use flowy_grid_data_model::entities::{ use std::collections::HashMap; use crate::services::row::{ - make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, CreateRowContext, - CreateRowContextBuilder, + make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -82,18 +81,28 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_row(&self) -> FlowyResult<()> { + pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult { let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; - let create_row_ctx = CreateRowContextBuilder::new(&field_metas).build(); - let row = row_meta_from_context(&block_id, create_row_ctx); - let row_count = self.block_meta_manager.create_row(row).await?; + + // insert empty row below the row whose id is upper_row_id + let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build(); + let row_meta = row_meta_from_context(&block_id, row_meta_ctx); + + // insert the row + let row_count = self + .block_meta_manager + .create_row(row_meta.clone(), upper_row_id) + .await?; + let row = make_rows(&field_metas, vec![row_meta.into()]).pop().unwrap(); + + // update block row count let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; - Ok(()) + Ok(row) } - pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { let block_id = self.last_block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); for ctx in contexts { diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 676411e8c7..ce8ac6e53d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -3,19 +3,19 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; -pub struct CreateRowContextBuilder<'a> { +pub struct RowMetaContextBuilder<'a> { field_meta_map: HashMap<&'a String, &'a FieldMeta>, - ctx: CreateRowContext, + ctx: RowMetaContext, } -impl<'a> CreateRowContextBuilder<'a> { +impl<'a> RowMetaContextBuilder<'a> { pub fn new(fields: &'a [FieldMeta]) -> Self { let field_meta_map = fields .iter() .map(|field| (&field.id, field)) .collect::>(); - let ctx = CreateRowContext { + let ctx = RowMetaContext { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, @@ -52,12 +52,12 @@ impl<'a> CreateRowContextBuilder<'a> { self } - pub fn build(self) -> CreateRowContext { + pub fn build(self) -> RowMetaContext { self.ctx } } -pub fn row_meta_from_context(block_id: &str, ctx: CreateRowContext) -> RowMeta { +pub fn row_meta_from_context(block_id: &str, ctx: RowMetaContext) -> RowMeta { RowMeta { id: ctx.row_id, block_id: block_id.to_owned(), @@ -67,7 +67,7 @@ pub fn row_meta_from_context(block_id: &str, ctx: CreateRowContext) -> RowMeta { } } -pub struct CreateRowContext { +pub struct RowMetaContext { pub row_id: String, pub cell_by_field_id: HashMap, pub height: i32, diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index aa114c3d07..02a6f760e0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -2,6 +2,7 @@ use crate::services::row::deserialize_cell_data; use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; +use std::ops::Deref; use std::sync::Arc; pub(crate) struct RowIdsPerBlock { diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index e7417b5ea7..82d5399f9e 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -12,10 +12,11 @@ pub fn make_default_grid() -> BuildGridContext { let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) + .option(SelectOption::new("Unknown")) .option(SelectOption::new("Progress")); let single_select_field = FieldBuilder::new(single_select) - .name("Name") + .name("Status") .visibility(true) .field_type(FieldType::SingleSelect) .build(); diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index acb8e27c39..36c202f335 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -2,7 +2,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use chrono::NaiveDateTime; use flowy_grid::services::cell::*; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, RowMetaContextBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset, }; @@ -179,7 +179,7 @@ async fn grid_create_row() { #[tokio::test] async fn grid_create_row2() { let mut test = GridEditorTest::new().await; - let create_row_context = CreateRowContextBuilder::new(&test.field_metas).build(); + let create_row_context = RowMetaContextBuilder::new(&test.field_metas).build(); let scripts = vec![ AssertRowCount(3), CreateRow { @@ -193,7 +193,7 @@ async fn grid_create_row2() { #[tokio::test] async fn grid_update_row() { let mut test = GridEditorTest::new().await; - let context = CreateRowContextBuilder::new(&test.field_metas).build(); + let context = RowMetaContextBuilder::new(&test.field_metas).build(); let changeset = RowMetaChangeset { row_id: context.row_id.clone(), height: None, @@ -216,8 +216,8 @@ async fn grid_update_row() { #[tokio::test] async fn grid_delete_row() { let mut test = GridEditorTest::new().await; - let context_1 = CreateRowContextBuilder::new(&test.field_metas).build(); - let context_2 = CreateRowContextBuilder::new(&test.field_metas).build(); + let context_1 = RowMetaContextBuilder::new(&test.field_metas).build(); + let context_2 = RowMetaContextBuilder::new(&test.field_metas).build(); let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let scripts = vec![ AssertRowCount(3), @@ -242,7 +242,7 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_row_add_cells_test() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut builder = RowMetaContextBuilder::new(&test.field_metas); for field in &test.field_metas { match field.field_type { FieldType::RichText => { @@ -288,7 +288,7 @@ async fn grid_row_add_cells_test() { #[tokio::test] async fn grid_row_add_selection_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut builder = RowMetaContextBuilder::new(&test.field_metas); let uuid = uuid::Uuid::new_v4().to_string(); let mut single_select_field_id = "".to_string(); let mut multi_select_field_id = "".to_string(); @@ -343,7 +343,7 @@ async fn grid_row_add_selection_cell_test() { #[tokio::test] async fn grid_row_add_date_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut builder = RowMetaContextBuilder::new(&test.field_metas); let mut date_field = None; let timestamp = 1647390674; for field in &test.field_metas { @@ -373,8 +373,11 @@ async fn grid_cell_update() { let mut test = GridEditorTest::new().await; let field_metas = &test.field_metas; let row_metas = &test.row_metas; + let grid_blocks = &test.grid_blocks; assert_eq!(row_metas.len(), 3); + assert_eq!(grid_blocks.len(), 1); + let block_id = &grid_blocks.first().unwrap().id; let mut scripts = vec![]; for (index, row_meta) in row_metas.iter().enumerate() { for field_meta in field_metas { @@ -396,6 +399,7 @@ async fn grid_cell_update() { scripts.push(UpdateCell { changeset: CellMetaChangeset { + grid_id: block_id.to_string(), row_id: row_meta.id.clone(), field_id: field_meta.id.clone(), data: Some(data), @@ -416,6 +420,7 @@ async fn grid_cell_update() { scripts.push(UpdateCell { changeset: CellMetaChangeset { + grid_id: block_id.to_string(), row_id: row_meta.id.clone(), field_id: field_meta.id.clone(), data: Some(data), diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 2c784153be..a9bc34c18c 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -4,7 +4,7 @@ use flowy_collaboration::client_grid::GridBuilder; use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid::services::row::CreateRowContext; +use flowy_grid::services::row::RowMetaContext; use flowy_grid_data_model::entities::{ BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, @@ -50,7 +50,7 @@ pub enum EditorScript { }, CreateEmptyRow, CreateRow { - context: CreateRowContext, + context: RowMetaContext, }, UpdateRow { changeset: RowMetaChangeset, diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 840e4c28af..c1673259e9 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -36,8 +36,24 @@ impl GridBlockMetaPad { Self::from_delta(block_delta) } - pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { + pub fn add_row( + &mut self, + row: RowMeta, + upper_row_id: Option, + ) -> CollaborateResult> { self.modify(|rows| { + if let Some(upper_row_id) = upper_row_id { + if upper_row_id.is_empty() { + rows.insert(0, Arc::new(row)); + return Ok(Some(())); + } + + if let Some(index) = rows.iter().position(|row| row.id == upper_row_id) { + rows.insert(index, Arc::new(row)); + return Ok(Some(())); + } + } + rows.push(Arc::new(row)); Ok(Some(())) }) @@ -202,13 +218,85 @@ mod tests { visibility: false, }; - let change = pad.add_row(row).unwrap().unwrap(); + let change = pad.add_row(row, None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); } + #[test] + fn block_meta_insert_row() { + let mut pad = test_pad(); + let row_1 = test_row_meta("1", &pad); + let row_2 = test_row_meta("2", &pad); + let row_3 = test_row_meta("3", &pad); + + let change = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + ); + + let change = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":101},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + ); + + let change = pad.add_row(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":109},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# + ); + + assert_eq!(*pad.rows[0], row_1); + assert_eq!(*pad.rows[1], row_3); + assert_eq!(*pad.rows[2], row_2); + } + + fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { + RowMeta { + id: id.to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + } + } + + #[test] + fn block_meta_insert_row2() { + let mut pad = test_pad(); + let row_1 = test_row_meta("1", &pad); + let row_2 = test_row_meta("2", &pad); + let row_3 = test_row_meta("3", &pad); + + let _ = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); + + assert_eq!(*pad.rows[0], row_3); + assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[2], row_2); + } + + #[test] + fn block_meta_insert_row3() { + let mut pad = test_pad(); + let row_1 = test_row_meta("1", &pad); + let row_2 = test_row_meta("2", &pad); + let row_3 = test_row_meta("3", &pad); + + let _ = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_3.clone(), Some("".to_string())).unwrap().unwrap(); + + assert_eq!(*pad.rows[0], row_3); + assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[2], row_2); + } + #[test] fn block_meta_delete_row() { let mut pad = test_pad(); @@ -221,7 +309,7 @@ mod tests { visibility: false, }; - let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let _ = pad.add_row(row.clone(), None).unwrap().unwrap(); let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), @@ -249,7 +337,7 @@ mod tests { cell_by_field_id: Default::default(), }; - let _ = pad.add_row(row).unwrap().unwrap(); + let _ = pad.add_row(row, None).unwrap().unwrap(); let change = pad.update_row(changeset).unwrap().unwrap(); assert_eq!( diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index e708dc8ee7..441cc7d39e 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -222,6 +222,15 @@ impl AsRef for GridId { } } +#[derive(ProtoBuf, Default)] +pub struct CreateRowPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2, one_of)] + pub upper_row_id: Option, +} + #[derive(ProtoBuf, Default)] pub struct QueryFieldPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index d70d17e0e9..34d323c5df 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -290,12 +290,15 @@ impl CellMeta { #[derive(Debug, Clone, Default, ProtoBuf)] pub struct CellMetaChangeset { #[pb(index = 1)] - pub row_id: String, + pub grid_id: String, #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] pub field_id: String, - #[pb(index = 3, one_of)] + #[pb(index = 4, one_of)] pub data: Option, } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 4070675fd6..abe55edbad 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -2433,6 +2433,247 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct CreateRowPayload { + // message fields + pub grid_id: ::std::string::String, + // message oneof groups + pub one_of_upper_row_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateRowPayload { + fn default() -> &'a CreateRowPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CreateRowPayload_oneof_one_of_upper_row_id { + upper_row_id(::std::string::String), +} + +impl CreateRowPayload { + pub fn new() -> CreateRowPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string upper_row_id = 2; + + + pub fn get_upper_row_id(&self) -> &str { + match self.one_of_upper_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v)) => v, + _ => "", + } + } + pub fn clear_upper_row_id(&mut self) { + self.one_of_upper_row_id = ::std::option::Option::None; + } + + pub fn has_upper_row_id(&self) -> bool { + match self.one_of_upper_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_upper_row_id(&mut self, v: ::std::string::String) { + self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_upper_row_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(_)) = self.one_of_upper_row_id { + } else { + self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(::std::string::String::new())); + } + match self.one_of_upper_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_upper_row_id(&mut self) -> ::std::string::String { + if self.has_upper_row_id() { + match self.one_of_upper_row_id.take() { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for CreateRowPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + match v { + &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + my_size += ::protobuf::rt::string_size(2, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + match v { + &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + os.write_string(2, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CreateRowPayload { + CreateRowPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &CreateRowPayload| { &m.grid_id }, + |m: &mut CreateRowPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "upper_row_id", + CreateRowPayload::has_upper_row_id, + CreateRowPayload::get_upper_row_id, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateRowPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateRowPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateRowPayload::new) + } +} + +impl ::protobuf::Clear for CreateRowPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.one_of_upper_row_id = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateRowPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateRowPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct QueryFieldPayload { // message fields @@ -2890,11 +3131,14 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ \x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPayload\x12\x12\n\x04n\ ame\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\ - \x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\ - \x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\x0fQueryRowPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\ - \x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrdersb\x06proto3\ + \x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\ + \x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\x02\x20\x01(\ + \tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryFieldPaylo\ + ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ + ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ + \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ + rsb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 9a90b67f81..d56f2ee5a3 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -2793,6 +2793,7 @@ impl ::protobuf::reflect::ProtobufValue for CellMeta { #[derive(PartialEq,Clone,Default)] pub struct CellMetaChangeset { // message fields + pub grid_id: ::std::string::String, pub row_id: ::std::string::String, pub field_id: ::std::string::String, // message oneof groups @@ -2818,7 +2819,33 @@ impl CellMetaChangeset { ::std::default::Default::default() } - // string row_id = 1; + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string row_id = 2; pub fn get_row_id(&self) -> &str { @@ -2844,7 +2871,7 @@ impl CellMetaChangeset { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } - // string field_id = 2; + // string field_id = 3; pub fn get_field_id(&self) -> &str { @@ -2870,7 +2897,7 @@ impl CellMetaChangeset { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string data = 3; + // string data = 4; pub fn get_data(&self) -> &str { @@ -2930,12 +2957,15 @@ impl ::protobuf::Message for CellMetaChangeset { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -2953,16 +2983,19 @@ impl ::protobuf::Message for CellMetaChangeset { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.row_id); + my_size += ::protobuf::rt::string_size(2, &self.row_id); } if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.field_id); + my_size += ::protobuf::rt::string_size(3, &self.field_id); } if let ::std::option::Option::Some(ref v) = self.one_of_data { match v { &CellMetaChangeset_oneof_one_of_data::data(ref v) => { - my_size += ::protobuf::rt::string_size(3, &v); + my_size += ::protobuf::rt::string_size(4, &v); }, }; } @@ -2972,16 +3005,19 @@ impl ::protobuf::Message for CellMetaChangeset { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } if !self.row_id.is_empty() { - os.write_string(1, &self.row_id)?; + os.write_string(2, &self.row_id)?; } if !self.field_id.is_empty() { - os.write_string(2, &self.field_id)?; + os.write_string(3, &self.field_id)?; } if let ::std::option::Option::Some(ref v) = self.one_of_data { match v { &CellMetaChangeset_oneof_one_of_data::data(ref v) => { - os.write_string(3, v)?; + os.write_string(4, v)?; }, }; } @@ -3023,6 +3059,11 @@ impl ::protobuf::Message for CellMetaChangeset { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &CellMetaChangeset| { &m.grid_id }, + |m: &mut CellMetaChangeset| { &mut m.grid_id }, + )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", |m: &CellMetaChangeset| { &m.row_id }, @@ -3054,6 +3095,7 @@ impl ::protobuf::Message for CellMetaChangeset { impl ::protobuf::Clear for CellMetaChangeset { fn clear(&mut self) { + self.grid_id.clear(); self.row_id.clear(); self.field_id.clear(); self.one_of_data = ::std::option::Option::None; @@ -3455,16 +3497,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\x08Cell\ Meta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04d\ - ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\ - ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\ - (\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\ - \x0bone_of_data\"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\ - \x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\ - \x02\x20\x01(\x0b2\n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\ - \x03\x20\x01(\x0b2\x0e.GridBlockMetaR\rgridBlockMeta*d\n\tFieldType\x12\ - \x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\ - \x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\ - \x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + ata\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ + \x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07field\ + Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\ + \"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\ + \x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\x02\x20\x01(\x0b2\ + \n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\x03\x20\x01(\x0b2\ + \x0e.GridBlockMetaR\rgridBlockMeta*d\n\tFieldType\x12\x0c\n\x08RichText\ + \x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\ + \x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08C\ + heckbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 66dba465f6..7f01016174 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -49,6 +49,10 @@ message CreateGridPayload { message GridId { string value = 1; } +message CreateRowPayload { + string grid_id = 1; + oneof one_of_upper_row_id { string upper_row_id = 2; }; +} message QueryFieldPayload { string grid_id = 1; RepeatedFieldOrder field_orders = 2; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 12447f6e8f..b1c8b77c40 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -56,9 +56,10 @@ message CellMeta { string data = 2; } message CellMetaChangeset { - string row_id = 1; - string field_id = 2; - oneof one_of_data { string data = 3; }; + string grid_id = 1; + string row_id = 2; + string field_id = 3; + oneof one_of_data { string data = 4; }; } message BuildGridContext { repeated FieldMeta field_metas = 1; From 694c612c67179631dab2ff0b7bd529328e3966ab Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 16:34:38 +0800 Subject: [PATCH 043/179] fix: event handler not found for ApplyDocDelta --- .../application/doc/doc_service.dart | 2 +- .../application/doc/share_service.dart | 2 +- .../dart_event/flowy-folder/dart_event.dart | 34 ------------------- .../flowy-folder/event_map.pbenum.dart | 4 --- .../flowy-folder/event_map.pbjson.dart | 4 +-- .../rust-lib/flowy-folder/src/event_map.rs | 6 ---- .../src/protobuf/model/event_map.rs | 11 ++---- .../src/protobuf/proto/event_map.proto | 2 -- 8 files changed, 5 insertions(+), 60 deletions(-) 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 8cda1bb087..01b0d6818a 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart @@ -18,7 +18,7 @@ class DocumentService { final payload = BlockDelta.create() ..blockId = docId ..deltaStr = data; - return FolderEventApplyDocDelta(payload).send(); + return BlockEventApplyDelta(payload).send(); } Future> closeDocument({required String docId}) { 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 26f27cca99..a01117aa7e 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/share_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/share_service.dart @@ -10,7 +10,7 @@ class ShareService { ..viewId = docId ..exportType = type; - return FolderEventExportDocument(request).send(); + return BlockEventExportDocument(request).send(); } Future> exportText(String docId) { 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 27986fc1c8..48549a5f28 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 @@ -377,37 +377,3 @@ class FolderEventDeleteAllTrash { } } -class FolderEventApplyDocDelta { - BlockDelta request; - FolderEventApplyDocDelta(this.request); - - Future> send() { - final request = FFIRequest.create() - ..event = FolderEvent.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 FolderEventExportDocument { - ExportPayload request; - FolderEventExportDocument(this.request); - - Future> send() { - final request = FFIRequest.create() - ..event = FolderEvent.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/protobuf/flowy-folder/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart index 5567086c85..73484cead5 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 @@ -33,8 +33,6 @@ class FolderEvent extends $pb.ProtobufEnum { static const FolderEvent DeleteTrash = FolderEvent._(302, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteTrash'); static const FolderEvent RestoreAllTrash = FolderEvent._(303, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RestoreAllTrash'); static const FolderEvent DeleteAllTrash = FolderEvent._(304, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteAllTrash'); - static const FolderEvent ApplyDocDelta = FolderEvent._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplyDocDelta'); - static const FolderEvent ExportDocument = FolderEvent._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ExportDocument'); static const $core.List values = [ CreateWorkspace, @@ -60,8 +58,6 @@ class FolderEvent extends $pb.ProtobufEnum { DeleteTrash, RestoreAllTrash, DeleteAllTrash, - ApplyDocDelta, - ExportDocument, ]; static final $core.Map<$core.int, FolderEvent> _byValue = $pb.ProtobufEnum.initByValue(values); 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 513dc1611c..136849065b 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 @@ -35,10 +35,8 @@ const FolderEvent$json = const { const {'1': 'DeleteTrash', '2': 302}, const {'1': 'RestoreAllTrash', '2': 303}, const {'1': 'DeleteAllTrash', '2': 304}, - const {'1': 'ApplyDocDelta', '2': 400}, - const {'1': 'ExportDocument', '2': 500}, ], }; /// Descriptor for `FolderEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAhISCg1BcHBseURvY0RlbHRhEJADEhMKDkV4cG9ydERvY3VtZW50EPQD'); +final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAg=='); diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 02e28d4c50..a470e289e5 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -147,12 +147,6 @@ pub enum FolderEvent { #[event()] DeleteAllTrash = 304, - - #[event(input = "BlockDelta", output = "BlockDelta")] - ApplyDocDelta = 400, - - #[event(input = "ExportPayload", output = "ExportData")] - ExportDocument = 500, } pub trait FolderCouldServiceV1: Send + Sync { 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 6552c3b30f..6dc25807d6 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 @@ -48,8 +48,6 @@ pub enum FolderEvent { DeleteTrash = 302, RestoreAllTrash = 303, DeleteAllTrash = 304, - ApplyDocDelta = 400, - ExportDocument = 500, } impl ::protobuf::ProtobufEnum for FolderEvent { @@ -82,8 +80,6 @@ impl ::protobuf::ProtobufEnum for FolderEvent { 302 => ::std::option::Option::Some(FolderEvent::DeleteTrash), 303 => ::std::option::Option::Some(FolderEvent::RestoreAllTrash), 304 => ::std::option::Option::Some(FolderEvent::DeleteAllTrash), - 400 => ::std::option::Option::Some(FolderEvent::ApplyDocDelta), - 500 => ::std::option::Option::Some(FolderEvent::ExportDocument), _ => ::std::option::Option::None } } @@ -113,8 +109,6 @@ impl ::protobuf::ProtobufEnum for FolderEvent { FolderEvent::DeleteTrash, FolderEvent::RestoreAllTrash, FolderEvent::DeleteAllTrash, - FolderEvent::ApplyDocDelta, - FolderEvent::ExportDocument, ]; values } @@ -143,7 +137,7 @@ impl ::protobuf::reflect::ProtobufValue for FolderEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xd7\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ + \n\x0fevent_map.proto*\xae\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\ @@ -154,8 +148,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \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\ + \x02\x12\x13\n\x0eDeleteAllTrash\x10\xb0\x02b\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 9c7d32f3e1..67f2606664 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 @@ -24,6 +24,4 @@ enum FolderEvent { DeleteTrash = 302; RestoreAllTrash = 303; DeleteAllTrash = 304; - ApplyDocDelta = 400; - ExportDocument = 500; } From 7fd06361b39d7698950d027b5a34b9c971803516 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 17:39:36 +0800 Subject: [PATCH 044/179] fix: git protocol security issue --- frontend/app_flowy/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 7f642f51b3..41ee902083 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -53,7 +53,7 @@ dependencies: path_provider: ^2.0.1 window_size: git: - url: git://github.com/google/flutter-desktop-embedding.git + url: https://github.com/google/flutter-desktop-embedding.git path: plugins/window_size ref: e48abe7c3e9ebfe0b81622167c5201d4e783bb81 sized_context: ^1.0.0+1 From 1237962ab2d656653799dd39ae5f5b960b581883 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 21:19:51 +0800 Subject: [PATCH 045/179] chore: config notification of grid --- .../lib/core/notification_helper.dart | 20 +- .../lib/startup/home_deps_resolver.dart | 7 +- .../workspace/application/grid/grid_bloc.dart | 23 ++- .../application/grid/grid_listener.dart | 60 ++++++ .../application/view/view_listener.dart | 12 +- .../plugins/grid/src/grid_page.dart | 3 +- .../flowy-grid-data-model/grid.pb.dart | 41 ++++ .../flowy-grid-data-model/grid.pbjson.dart | 10 + .../flowy-grid/dart_notification.pb.dart | 11 ++ .../flowy-grid/dart_notification.pbenum.dart | 34 ++++ .../flowy-grid/dart_notification.pbjson.dart | 25 +++ .../dart_notification.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 1 + frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- .../flowy-grid/src/dart_notification.rs | 36 ++++ .../rust-lib/flowy-grid/src/event_handler.rs | 6 +- frontend/rust-lib/flowy-grid/src/lib.rs | 1 + .../src/protobuf/model/dart_notification.rs | 106 ++++++++++ .../flowy-grid/src/protobuf/model/mod.rs | 3 + .../protobuf/proto/dart_notification.proto | 10 + .../src/services/block_meta_editor.rs | 127 +++++++++--- .../flowy-grid/src/services/grid_editor.rs | 48 +++-- .../flowy-grid/src/services/row/row_loader.rs | 12 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 2 +- .../src/client_grid/grid_meta_pad.rs | 20 +- .../src/entities/grid.rs | 25 +++ .../src/protobuf/model/grid.rs | 187 +++++++++++++++++- .../src/protobuf/proto/grid.proto | 3 + 28 files changed, 763 insertions(+), 81 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/dart_notification.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto diff --git a/frontend/app_flowy/lib/core/notification_helper.dart b/frontend/app_flowy/lib/core/notification_helper.dart index 88b299aa3a..d815bf92bb 100644 --- a/frontend/app_flowy/lib/core/notification_helper.dart +++ b/frontend/app_flowy/lib/core/notification_helper.dart @@ -4,7 +4,9 @@ import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +// User typedef UserNotificationCallback = void Function(UserNotification, Either); class UserNotificationParser extends NotificationParser { @@ -17,10 +19,11 @@ class UserNotificationParser extends NotificationParser); +// Folder +typedef FolderNotificationCallback = void Function(FolderNotification, Either); class FolderNotificationParser extends NotificationParser { - FolderNotificationParser({String? id, required NotificationCallback callback}) + FolderNotificationParser({String? id, required FolderNotificationCallback callback}) : super( id: id, callback: callback, @@ -29,6 +32,19 @@ class FolderNotificationParser extends NotificationParser); + +class GridNotificationParser extends NotificationParser { + GridNotificationParser({String? id, required GridNotificationCallback callback}) + : super( + id: id, + callback: callback, + tyParser: (ty) => GridNotification.valueOf(ty), + errorParser: (bytes) => FlowyError.fromBuffer(bytes), + ); +} + class NotificationParser { String? id; void Function(T, Either) callback; diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index cbb359f09d..d66fe7cc01 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -16,6 +16,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; +import '../workspace/application/grid/grid_listener.dart'; + class HomeDepsResolver { static Future resolve(GetIt getIt) async { getIt.registerFactoryParam( @@ -90,10 +92,7 @@ class HomeDepsResolver { // Grid getIt.registerFactoryParam( - (view, _) => GridBloc( - view: view, - service: GridService(), - ), + (view, _) => GridBloc(view: view, service: GridService(), listener: GridListener(gridId: view.id)), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index b67f119fe3..09e4428a83 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,13 +1,14 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; - import 'data.dart'; +import 'grid_listener.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -15,14 +16,16 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final GridService service; final View view; + final GridListener listener; Grid? _grid; List? _fields; - GridBloc({required this.view, required this.service}) : super(GridState.initial()) { + GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) { on( (event, emit) async { await event.map( initial: (InitialGrid value) async { + await _startGridListening(); await _loadGrid(emit); await _loadFields(emit); await _loadGridInfo(emit); @@ -40,9 +43,25 @@ class GridBloc extends Bloc { @override Future close() async { + await listener.close(); return super.close(); } + Future _startGridListening() async { + listener.createRowNotifier.addPublishListener((result) { + result.fold((row) { + // + Log.info("$row"); + }, (err) => null); + }); + + listener.deleteRowNotifier.addPublishListener((result) { + result.fold((l) => null, (r) => null); + }); + + listener.start(); + } + Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); result.fold( diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index e69de29bb2..b17544edf9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -0,0 +1,60 @@ +import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; +import 'package:dartz/dartz.dart'; + +typedef CreateRowNotifiedValue = Either; +typedef DeleteRowNotifierValue = Either; + +class GridListener { + final String gridId; + PublishNotifier createRowNotifier = PublishNotifier(); + PublishNotifier deleteRowNotifier = PublishNotifier(); + StreamSubscription? _subscription; + late GridNotificationParser _parser; + + GridListener({required this.gridId}); + + void start() { + _parser = GridNotificationParser( + id: gridId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.GridDidCreateRows: + result.fold( + (payload) => createRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), + (error) => createRowNotifier.value = right(error), + ); + break; + case GridNotification.GridDidDeleteRow: + result.fold( + (payload) => deleteRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), + (error) => deleteRowNotifier.value = right(error), + ); + break; + + default: + break; + } + } + + Future close() async { + await _subscription?.cancel(); + createRowNotifier.dispose(); + deleteRowNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart index c5a202e25e..f400124805 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart @@ -9,15 +9,15 @@ import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart'; import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; -typedef DeleteNotifierValue = Either; -typedef UpdateNotifierValue = Either; -typedef RestoreNotifierValue = Either; +typedef DeleteViewNotifyValue = Either; +typedef UpdateViewNotifiedValue = Either; +typedef RestoreViewNotifiedValue = Either; class ViewListener { StreamSubscription? _subscription; - PublishNotifier updatedNotifier = PublishNotifier(); - PublishNotifier deletedNotifier = PublishNotifier(); - PublishNotifier restoredNotifier = PublishNotifier(); + PublishNotifier updatedNotifier = PublishNotifier(); + PublishNotifier deletedNotifier = PublishNotifier(); + PublishNotifier restoredNotifier = PublishNotifier(); late FolderNotificationParser _parser; View view; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 7435ea0e5f..c396e7d71f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -139,9 +139,10 @@ class _GridBodyState extends State { delegate: SliverChildBuilderDelegate( (context, index) { final data = gridInfo.rowAtIndex(index); - return RepaintBoundary(child: GridRowWidget(data: data)); + return GridRowWidget(data: data); }, childCount: gridInfo.numberOfRows(), + addRepaintBoundaries: true, ), ); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index f89285ba92..21f7e0f4a8 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -607,6 +607,47 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(2); } +class RepeatedCell extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedCell', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Cell.create) + ..hasRequiredFields = false + ; + + RepeatedCell._() : super(); + factory RepeatedCell({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedCell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedCell clone() => RepeatedCell()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedCell copyWith(void Function(RepeatedCell) updates) => super.copyWith((message) => updates(message as RepeatedCell)) as RepeatedCell; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedCell create() => RepeatedCell._(); + RepeatedCell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedCell? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class CreateGridPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateGridPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 1504b31506..a6a7eb79d3 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -131,6 +131,16 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); +@$core.Deprecated('Use repeatedCellDescriptor instead') +const RepeatedCell$json = const { + '1': 'RepeatedCell', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Cell', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedCell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedCellDescriptor = $convert.base64Decode('CgxSZXBlYXRlZENlbGwSGwoFaXRlbXMYASADKAsyBS5DZWxsUgVpdGVtcw=='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart new file mode 100644 index 0000000000..402c0a4115 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart @@ -0,0 +1,11 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +export 'dart_notification.pbenum.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart new file mode 100644 index 0000000000..9f4245122f --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -0,0 +1,34 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class GridNotification extends $pb.ProtobufEnum { + static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); + static const GridNotification GridDidCreateRows = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateRows'); + static const GridNotification GridDidDeleteRow = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidDeleteRow'); + static const GridNotification GridDidUpdateRows = GridNotification._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateRows'); + static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); + static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); + + static const $core.List values = [ + Unknown, + GridDidCreateRows, + GridDidDeleteRow, + GridDidUpdateRows, + GridDidUpdateCells, + GridDidUpdateFields, + ]; + + static final $core.Map<$core.int, GridNotification> _byValue = $pb.ProtobufEnum.initByValue(values); + static GridNotification? valueOf($core.int value) => _byValue[value]; + + const GridNotification._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart new file mode 100644 index 0000000000..5100550835 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -0,0 +1,25 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use gridNotificationDescriptor instead') +const GridNotification$json = const { + '1': 'GridNotification', + '2': const [ + const {'1': 'Unknown', '2': 0}, + const {'1': 'GridDidCreateRows', '2': 10}, + const {'1': 'GridDidDeleteRow', '2': 11}, + const {'1': 'GridDidUpdateRows', '2': 12}, + const {'1': 'GridDidUpdateCells', '2': 20}, + const {'1': 'GridDidUpdateFields', '2': 30}, + ], +}; + +/// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIVChFHcmlkRGlkQ3JlYXRlUm93cxAKEhQKEEdyaWREaWREZWxldGVSb3cQCxIVChFHcmlkRGlkVXBkYXRlUm93cxAMEhYKEkdyaWREaWRVcGRhdGVDZWxscxAUEhcKE0dyaWREaWRVcGRhdGVGaWVsZHMQHg=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart new file mode 100644 index 0000000000..8be819e83e --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'dart_notification.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index 0ad090edd5..daefe6a170 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -1,6 +1,7 @@ // Auto-generated, do not edit export './date_description.pb.dart'; export './text_description.pb.dart'; +export './dart_notification.pb.dart'; export './checkbox_description.pb.dart'; export './selection_description.pb.dart'; export './event_map.pb.dart'; diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index 4d1a277df3..b310e3fcd7 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/cell/description"] +proto_crates = ["src/event_map.rs", "src/services/cell/description", "src/dart_notification.rs"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs new file mode 100644 index 0000000000..d6fb15d719 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -0,0 +1,36 @@ +use dart_notify::DartNotifyBuilder; +use flowy_derive::ProtoBuf_Enum; +const OBSERVABLE_CATEGORY: &str = "Grid"; + +#[derive(ProtoBuf_Enum, Debug)] +pub enum GridNotification { + Unknown = 0, + GridDidCreateRows = 10, + GridDidDeleteRow = 11, + GridDidUpdateRows = 12, + + GridDidUpdateCells = 20, + GridDidUpdateFields = 30, +} + +impl std::default::Default for GridNotification { + fn default() -> Self { + GridNotification::Unknown + } +} + +impl std::convert::From for i32 { + fn from(notification: GridNotification) -> Self { + notification as i32 + } +} + +#[tracing::instrument(level = "trace")] +pub fn send_dart_notification(id: &str, ty: GridNotification) -> DartNotifyBuilder { + DartNotifyBuilder::new(id, ty, OBSERVABLE_CATEGORY) +} + +#[tracing::instrument(level = "trace")] +pub fn send_anonymous_dart_notification(ty: GridNotification) -> DartNotifyBuilder { + DartNotifyBuilder::new("", ty, OBSERVABLE_CATEGORY) +} diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e92556b554..9d0001305d 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -45,11 +45,11 @@ pub(crate) async fn get_fields_handler( pub(crate) async fn create_row_handler( data: Data, manager: AppData>, -) -> DataResult { +) -> Result<(), FlowyError> { let payload: CreateRowPayload = data.into_inner(); let editor = manager.get_grid_editor(payload.grid_id.as_ref())?; - let row = editor.create_row(payload.upper_row_id).await?; - data_result(row) + let _ = editor.create_row(payload.upper_row_id).await?; + Ok(()) } #[tracing::instrument(level = "debug", skip_all, err)] diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 526e1e4267..a3ac3411e2 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -5,6 +5,7 @@ mod event_handler; pub mod event_map; pub mod manager; +mod dart_notification; mod protobuf; pub mod services; pub mod util; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs new file mode 100644 index 0000000000..63676bd6e6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -0,0 +1,106 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `dart_notification.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum GridNotification { + Unknown = 0, + GridDidCreateRows = 10, + GridDidDeleteRow = 11, + GridDidUpdateRows = 12, + GridDidUpdateCells = 20, + GridDidUpdateFields = 30, +} + +impl ::protobuf::ProtobufEnum for GridNotification { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(GridNotification::Unknown), + 10 => ::std::option::Option::Some(GridNotification::GridDidCreateRows), + 11 => ::std::option::Option::Some(GridNotification::GridDidDeleteRow), + 12 => ::std::option::Option::Some(GridNotification::GridDidUpdateRows), + 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), + 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [GridNotification] = &[ + GridNotification::Unknown, + GridNotification::GridDidCreateRows, + GridNotification::GridDidDeleteRow, + GridNotification::GridDidUpdateRows, + GridNotification::GridDidUpdateCells, + GridNotification::GridDidUpdateFields, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("GridNotification", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for GridNotification { +} + +impl ::std::default::Default for GridNotification { + fn default() -> Self { + GridNotification::Unknown + } +} + +impl ::protobuf::reflect::ProtobufValue for GridNotification { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x17dart_notification.proto*\x94\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x15\n\x11GridDidCreateRows\x10\n\x12\x14\n\x10Grid\ + DidDeleteRow\x10\x0b\x12\x15\n\x11GridDidUpdateRows\x10\x0c\x12\x16\n\ + \x12GridDidUpdateCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\ + \x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index fb32dca3f2..a616a281d6 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -7,6 +7,9 @@ pub use date_description::*; mod text_description; pub use text_description::*; +mod dart_notification; +pub use dart_notification::*; + mod checkbox_description; pub use checkbox_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto new file mode 100644 index 0000000000..9c606ac091 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +enum GridNotification { + Unknown = 0; + GridDidCreateRows = 10; + GridDidDeleteRow = 11; + GridDidUpdateRows = 12; + GridDidUpdateCells = 20; + GridDidUpdateFields = 30; +} diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 0da4b9e609..8e49a47588 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,5 +1,5 @@ use crate::manager::GridUser; -use crate::services::row::make_row_ids_per_block; +use crate::services::row::{make_cell, make_row_ids_per_block, make_rows}; use bytes::Bytes; use dashmap::DashMap; @@ -8,7 +8,8 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - GridBlock, GridBlockChangeset, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, + Cell, FieldMeta, GridBlock, GridBlockChangeset, RepeatedCell, RepeatedRow, RepeatedRowOrder, RowMeta, + RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -19,6 +20,7 @@ use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; +use crate::dart_notification::{send_dart_notification, GridNotification}; use std::sync::Arc; use tokio::sync::RwLock; @@ -26,17 +28,20 @@ type RowId = String; type BlockId = String; pub(crate) struct GridBlockMetaEditorManager { + grid_id: String, user: Arc, editor_map: DashMap>, block_id_by_row_id: DashMap, } impl GridBlockMetaEditorManager { - pub(crate) async fn new(user: &Arc, blocks: Vec) -> FlowyResult { + pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); let block_id_by_row_id = DashMap::new(); + let grid_id = grid_id.to_owned(); let manager = Self { + grid_id, user, editor_map, block_id_by_row_id, @@ -56,25 +61,41 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { - self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); - let editor = self.get_editor(&row.block_id).await?; - editor.create_row(row, upper_row_id).await + pub(crate) async fn create_row( + &self, + field_metas: &[FieldMeta], + row_meta: RowMeta, + upper_row_id: Option, + ) -> FlowyResult { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + let editor = self.get_editor(&row_meta.block_id).await?; + + let rows = make_rows(field_metas, vec![row_meta.clone().into()]); + send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) + .payload(RepeatedRow::from(rows)) + .send(); + + self.notify_did_create_rows(field_metas, vec![row_meta.clone()]); + + editor.create_row(row_meta, upper_row_id).await } pub(crate) async fn insert_row( &self, + field_metas: &[FieldMeta], rows_by_block_id: HashMap>, ) -> FlowyResult> { let mut changesets = vec![]; - for (block_id, rows) in rows_by_block_id { + for (block_id, row_metas) in rows_by_block_id { let editor = self.get_editor(&block_id).await?; let mut row_count = 0; - for row in rows { + for row in &row_metas { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); - row_count = editor.create_row(row, None).await?; + row_count = editor.create_row(row.clone(), None).await?; } changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); + self.notify_did_create_rows(field_metas, row_metas); } Ok(changesets) @@ -104,19 +125,17 @@ impl GridBlockMetaEditorManager { } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { - match self.block_id_by_row_id.get(&changeset.row_id) { - None => { - let msg = format!( - "Update Row failed. Can't find the corresponding block with row_id: {}", - changeset.row_id - ); - Err(FlowyError::internal().context(msg)) - } - Some(block_id) => { - let editor = self.get_editor(&block_id).await?; - editor.update_row(changeset).await - } - } + let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let _ = editor.update_row(changeset.clone()).await?; + let _ = self.notify_did_update_row()?; + Ok(()) + } + + pub async fn update_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { + let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let _ = editor.update_row(changeset.clone()).await?; + self.notify_did_update_cells(changeset, field_metas)?; + Ok(()) } pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult>> { @@ -159,6 +178,68 @@ impl GridBlockMetaEditorManager { } Ok(row_metas) } + + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + match self.block_id_by_row_id.get(row_id) { + None => { + let msg = format!( + "Update Row failed. Can't find the corresponding block with row_id: {}", + row_id + ); + Err(FlowyError::internal().context(msg)) + } + Some(block_id) => { + let editor = self.get_editor(&block_id).await?; + Ok(editor) + } + } + } + + fn notify_did_create_rows(&self, field_metas: &[FieldMeta], row_metas: Vec) { + let rows = make_rows( + field_metas, + row_metas + .into_iter() + .map(|row_meta| Arc::new(row_meta)) + .collect::>(), + ); + send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) + .payload(RepeatedRow::from(rows)) + .send(); + } + + fn notify_did_update_row(&self) -> FlowyResult<()> { + // send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateRows) + // .payload(RepeatedRow::from(cells)) + // .send(); + + todo!() + } + + fn notify_did_update_cells(&self, changeset: RowMetaChangeset, field_metas: &[FieldMeta]) -> FlowyResult<()> { + let field_meta_map = field_metas + .iter() + .map(|field_meta| (&field_meta.id, field_meta)) + .collect::>(); + + let mut cells = vec![]; + changeset + .cell_by_field_id + .into_iter() + .for_each( + |(field_id, cell_meta)| match make_cell(&field_meta_map, field_id, cell_meta) { + None => {} + Some((_, cell)) => cells.push(cell), + }, + ); + + if !cells.is_empty() { + send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateCells) + .payload(RepeatedCell::from(cells)) + .send(); + } + Ok(()) + } } async fn make_block_meta_editor_map( diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index f6730565ed..491a2831bb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,16 +1,17 @@ use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; use bytes::Bytes; -use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; +use flowy_collaboration::client_grid::{GridChangeset, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, - RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, + Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedField, + RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; +use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder, }; @@ -40,8 +41,9 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = - Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks().clone()).await?); + let block_meta_manager = Arc::new( + GridBlockMetaEditorManager::new(grid_id, &user, grid_meta_pad.read().await.get_blocks().clone()).await?, + ); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -54,6 +56,7 @@ impl ClientGridEditor { pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?; + let _ = self.notify_did_update_fields().await?; Ok(()) } @@ -81,7 +84,7 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult { + pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult<()> { let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; @@ -92,17 +95,17 @@ impl ClientGridEditor { // insert the row let row_count = self .block_meta_manager - .create_row(row_meta.clone(), upper_row_id) + .create_row(&field_metas, row_meta, upper_row_id) .await?; - let row = make_rows(&field_metas, vec![row_meta.into()]).pop().unwrap(); // update block row count let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; - Ok(row) + Ok(()) } pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); for ctx in contexts { @@ -112,7 +115,10 @@ impl ClientGridEditor { .or_insert_with(Vec::new) .push(row_meta); } - let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; + let changesets = self + .block_meta_manager + .insert_row(&field_metas, rows_by_block_id) + .await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } @@ -136,8 +142,13 @@ impl ClientGridEditor { } } + let field_metas = self.get_field_metas(None).await?; let row_changeset: RowMetaChangeset = changeset.into(); - self.update_row(row_changeset).await + let _ = self + .block_meta_manager + .update_cells(&field_metas, row_changeset) + .await?; + Ok(()) } pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { @@ -205,7 +216,7 @@ impl ClientGridEditor { async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { let mut write_guard = self.grid_meta_pad.write().await; match f(&mut *write_guard)? { @@ -217,8 +228,8 @@ impl ClientGridEditor { Ok(()) } - async fn apply_change(&self, change: GridChange) -> FlowyResult<()> { - let GridChange { delta, md5 } = change; + async fn apply_change(&self, change: GridChangeset) -> FlowyResult<()> { + let GridChangeset { delta, md5 } = change; let user_id = self.user.user_id()?; let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let delta_data = delta.to_delta_bytes(); @@ -243,6 +254,15 @@ impl ClientGridEditor { Some(grid_block) => Ok(grid_block.id.clone()), } } + + async fn notify_did_update_fields(&self) -> FlowyResult<()> { + let field_metas = self.get_field_metas(None).await?; + let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); + send_dart_notification(&self.grid_id, GridNotification::GridDidUpdateFields) + .payload(repeated_field) + .send(); + Ok(()) + } } #[cfg(feature = "flowy_unit_test")] diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 02a6f760e0..6283db0540 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -48,7 +48,11 @@ pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec>) -> V } #[inline(always)] -fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { +pub fn make_cell( + field_map: &HashMap<&String, &FieldMeta>, + field_id: String, + raw_cell: CellMeta, +) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; match deserialize_cell_data(raw_cell.data, field_meta) { Ok(content) => { @@ -63,9 +67,9 @@ fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cel } pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>) -> HashMap { - let field_map = fields + let field_meta_map = fields .iter() - .map(|field| (&field.id, field)) + .map(|field_meta| (&field_meta.id, field_meta)) .collect::>(); let make_row = |row_meta: Arc| { @@ -73,7 +77,7 @@ pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>(); let row = Row { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index a9bc34c18c..6449d09f6f 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -172,7 +172,7 @@ impl GridEditorTest { assert_eq!(compared_block, block); } EditorScript::CreateEmptyRow => { - self.editor.create_row().await.unwrap(); + self.editor.create_row(None).await.unwrap(); self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index e836034fae..a403b9c1c9 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -35,7 +35,7 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { + pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { self.modify_grid(|grid| { if grid.fields.contains(&field_meta) { tracing::warn!("Duplicate grid field"); @@ -47,7 +47,7 @@ impl GridMetaPad { }) } - pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { + pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { None => Ok(None), Some(index) => { @@ -95,7 +95,7 @@ impl GridMetaPad { } } - pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { + pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { let field_id = changeset.field_id.clone(); self.modify_field(&field_id, |field| { let mut is_changed = None; @@ -138,7 +138,7 @@ impl GridMetaPad { }) } - pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { + pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { if grid.blocks.iter().any(|b| b.id == block.id) { tracing::warn!("Duplicate grid block"); @@ -165,7 +165,7 @@ impl GridMetaPad { self.grid_meta.blocks.clone() } - pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { + pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; @@ -200,7 +200,7 @@ impl GridMetaPad { &self.grid_meta.fields } - fn modify_grid(&mut self, f: F) -> CollaborateResult> + fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut GridMeta) -> CollaborateResult>, { @@ -214,14 +214,14 @@ impl GridMetaPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(GridChange { delta, md5: self.md5() })) + Ok(Some(GridChangeset { delta, md5: self.md5() })) } } } } } - pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> + pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut GridBlock) -> CollaborateResult>, { @@ -234,7 +234,7 @@ impl GridMetaPad { }) } - pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> + pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut FieldMeta) -> CollaborateResult>, { @@ -254,7 +254,7 @@ fn json_from_grid(grid: &Arc) -> CollaborateResult { Ok(json) } -pub struct GridChange { +pub struct GridChangeset { pub delta: GridMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 441cc7d39e..36e8e211e3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -204,6 +204,31 @@ impl Cell { } } +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedCell { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::ops::Deref for RepeatedCell { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedCell { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +impl std::convert::From> for RepeatedCell { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index abe55edbad..9702766975 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -2115,6 +2115,172 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedCell { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedCell { + fn default() -> &'a RepeatedCell { + ::default_instance() + } +} + +impl RepeatedCell { + pub fn new() -> RepeatedCell { + ::std::default::Default::default() + } + + // repeated .Cell items = 1; + + + pub fn get_items(&self) -> &[Cell] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedCell { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedCell { + RepeatedCell::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedCell| { &m.items }, + |m: &mut RepeatedCell| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedCell", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedCell { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedCell::new) + } +} + +impl ::protobuf::Clear for RepeatedCell { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedCell { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedCell { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CreateGridPayload { // message fields @@ -3129,16 +3295,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\ \x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\";\n\x04Cell\x12\ \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ - \x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPayload\x12\x12\n\x04n\ - ame\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\ - \x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\x02\x20\x01(\ - \tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryFieldPaylo\ - ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ - ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ - \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ - rsb\x06proto3\ + \x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\ + \x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\ + \x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\ + \x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\ + \x02\x20\x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11Qu\ + eryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\ + \n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfiel\ + dOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ + R\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrde\ + rR\trowOrdersb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 7f01016174..ed6fc83b65 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -43,6 +43,9 @@ message Cell { string field_id = 1; string content = 2; } +message RepeatedCell { + repeated Cell items = 1; +} message CreateGridPayload { string name = 1; } From 4730ca9302a92058f64922b4bc0f278d186acd7c Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 17 Mar 2022 17:25:43 +0800 Subject: [PATCH 046/179] chore: refactor grid block --- .../lib/startup/home_deps_resolver.dart | 2 + .../lib/workspace/application/grid/data.dart | 4 +- .../workspace/application/grid/grid_bloc.dart | 22 +- .../application/grid/grid_listener.dart | 21 +- .../application/grid/grid_service.dart | 10 +- .../workspace/application/grid/row_bloc.dart | 27 +- .../application/grid/row_listener.dart | 54 ++ .../dart_event/flowy-grid/dart_event.dart | 12 +- .../flowy-grid-data-model/grid.pb.dart | 190 +++-- .../flowy-grid-data-model/grid.pbjson.dart | 49 +- .../flowy-grid-data-model/meta.pb.dart | 194 ++--- .../flowy-grid-data-model/meta.pbjson.dart | 38 +- .../flowy-grid/dart_notification.pbenum.dart | 8 +- .../flowy-grid/dart_notification.pbjson.dart | 6 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../flowy-grid/src/dart_notification.rs | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 16 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- frontend/rust-lib/flowy-grid/src/manager.rs | 4 +- .../src/protobuf/model/dart_notification.rs | 20 +- .../src/protobuf/model/event_map.rs | 12 +- .../protobuf/proto/dart_notification.proto | 4 +- .../src/protobuf/proto/event_map.proto | 2 +- .../src/services/block_meta_editor.rs | 179 +++-- .../flowy-grid/src/services/grid_editor.rs | 114 +-- .../flowy-grid/src/services/row/row_loader.rs | 110 ++- .../flowy-grid/tests/grid/grid_test.rs | 12 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 24 +- ...ock_pad.rs => grid_block_meta_data_pad.rs} | 64 +- .../src/client_grid/grid_builder.rs | 10 +- .../src/client_grid/grid_meta_pad.rs | 28 +- .../src/client_grid/mod.rs | 4 +- .../src/entities/grid.rs | 67 +- .../src/entities/meta.rs | 36 +- .../src/protobuf/model/grid.rs | 604 ++++++++++++--- .../src/protobuf/model/meta.rs | 707 +++++++++--------- .../src/protobuf/proto/grid.proto | 17 +- .../src/protobuf/proto/meta.proto | 18 +- 39 files changed, 1657 insertions(+), 1050 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row_listener.dart rename shared-lib/flowy-collaboration/src/client_grid/{block_pad.rs => grid_block_meta_data_pad.rs} (85%) diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index d66fe7cc01..084612ca61 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -3,6 +3,7 @@ import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/row_listener.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/view/prelude.dart'; @@ -98,6 +99,7 @@ class HomeDepsResolver { getIt.registerFactoryParam( (data, _) => RowBloc( service: RowService(data), + listener: RowListener(rowId: data.row.id), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 77cb1d9e6d..05ca053b8c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -3,12 +3,12 @@ import 'package:equatable/equatable.dart'; class GridInfo { final String gridId; - List rows; + List gridBlocks; List fields; GridInfo({ required this.gridId, - required this.rows, + required this.gridBlocks, required this.fields, }); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 09e4428a83..8fea0b04df 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -14,8 +14,8 @@ import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { - final GridService service; final View view; + final GridService service; final GridListener listener; Grid? _grid; List? _fields; @@ -49,9 +49,9 @@ class GridBloc extends Bloc { Future _startGridListening() async { listener.createRowNotifier.addPublishListener((result) { - result.fold((row) { + result.fold((repeatedRow) { // - Log.info("$row"); + Log.info("$repeatedRow"); }, (err) => null); }); @@ -91,10 +91,18 @@ class GridBloc extends Bloc { Future _loadGridInfo(Emitter emit) async { final grid = _grid; if (grid != null && _fields != null) { - final result = await service.getRows(gridId: grid.id, rowOrders: grid.rowOrders); - result.fold((repeatedRow) { - final rows = repeatedRow.items; - final gridInfo = GridInfo(gridId: grid.id, rows: rows, fields: _fields!); + final result = await service.getGridBlocks( + gridId: grid.id, + blocks: grid.blocks, + ); + + result.fold((repeatedGridBlock) { + final blocks = repeatedGridBlock.items; + final gridInfo = GridInfo( + gridId: grid.id, + blocks: blocks, + fields: _fields!, + ); emit( state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index b17544edf9..67f69b57b6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -9,13 +9,11 @@ import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; import 'package:dartz/dartz.dart'; -typedef CreateRowNotifiedValue = Either; -typedef DeleteRowNotifierValue = Either; +typedef GridBlockUpdateNotifiedValue = Either; class GridListener { final String gridId; - PublishNotifier createRowNotifier = PublishNotifier(); - PublishNotifier deleteRowNotifier = PublishNotifier(); + PublishNotifier blockUpdateNotifier = PublishNotifier(); StreamSubscription? _subscription; late GridNotificationParser _parser; @@ -34,16 +32,10 @@ class GridListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.GridDidCreateRows: + case GridNotification.GridDidUpdateBlock: result.fold( - (payload) => createRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), - (error) => createRowNotifier.value = right(error), - ); - break; - case GridNotification.GridDidDeleteRow: - result.fold( - (payload) => deleteRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), - (error) => deleteRowNotifier.value = right(error), + (payload) => blockUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), + (error) => blockUpdateNotifier.value = right(error), ); break; @@ -54,7 +46,6 @@ class GridListener { Future close() async { await _subscription?.cancel(); - createRowNotifier.dispose(); - deleteRowNotifier.dispose(); + blockUpdateNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 915cc671b6..62208c8d05 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,6 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridService { Future> openGrid({required String gridId}) async { @@ -18,11 +19,12 @@ class GridService { return GridEventCreateRow(payload).send(); } - Future> getRows({required String gridId, required List rowOrders}) { - final payload = QueryRowPayload.create() + Future> getGridBlocks( + {required String gridId, required List blocks}) { + final payload = QueryGridBlocksPayload.create() ..gridId = gridId - ..rowOrders = RepeatedRowOrder(items: rowOrders); - return GridEventGetRows(payload).send(); + ..blocks.addAll(blocks); + return GridEventGetGridBlocks(payload).send(); } Future> getFields({required String gridId, required List fieldOrders}) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 1dd20aad9a..16195af592 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -1,19 +1,24 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'data.dart'; +import 'row_listener.dart'; import 'row_service.dart'; part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { final RowService service; + final RowListener listener; - RowBloc({required this.service}) : super(RowState.initial(service.rowData)) { + RowBloc({required this.service, required this.listener}) : super(RowState.initial(service.rowData)) { on( (event, emit) async { await event.map( - initial: (_InitialRow value) async {}, + initial: (_InitialRow value) async { + _startRowListening(); + }, createRow: (_CreateRow value) { service.createRow(); }, @@ -30,8 +35,26 @@ class RowBloc extends Bloc { @override Future close() async { + await listener.close(); return super.close(); } + + Future _startRowListening() async { + listener.updateRowNotifier.addPublishListener((result) { + result.fold((row) { + // + }, (err) => null); + }); + + listener.updateCellNotifier.addPublishListener((result) { + result.fold((repeatedCvell) { + // + Log.info("$repeatedCvell"); + }, (r) => null); + }); + + listener.start(); + } } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart new file mode 100644 index 0000000000..76a2ba617d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart @@ -0,0 +1,54 @@ +import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; +import 'package:dartz/dartz.dart'; + +typedef UpdateCellNotifiedValue = Either; +typedef UpdateRowNotifiedValue = Either; + +class RowListener { + final String rowId; + PublishNotifier updateCellNotifier = PublishNotifier(); + PublishNotifier updateRowNotifier = PublishNotifier(); + StreamSubscription? _subscription; + late GridNotificationParser _parser; + + RowListener({required this.rowId}); + + void start() { + _parser = GridNotificationParser( + id: rowId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.GridDidUpdateCells: + result.fold( + (payload) => updateCellNotifier.value = left(RepeatedCell.fromBuffer(payload)), + (error) => updateCellNotifier.value = right(error), + ); + break; + + default: + break; + } + } + + Future close() async { + await _subscription?.cancel(); + updateCellNotifier.dispose(); + updateRowNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index 19c46c8306..10cb8bae79 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -18,18 +18,18 @@ class GridEventGetGridData { } } -class GridEventGetRows { - QueryRowPayload request; - GridEventGetRows(this.request); +class GridEventGetGridBlocks { + QueryGridBlocksPayload request; + GridEventGetGridBlocks(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() - ..event = GridEvent.GetRows.toString() + ..event = GridEvent.GetGridBlocks.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (okBytes) => left(RepeatedRow.fromBuffer(okBytes)), + (okBytes) => left(RepeatedGridBlock.fromBuffer(okBytes)), (errBytes) => right(FlowyError.fromBuffer(errBytes)), )); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 21f7e0f4a8..9b4dc19b7c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -9,13 +9,15 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'meta.pb.dart' as $0; + import 'meta.pbenum.dart' as $0; class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc<$0.GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) ..hasRequiredFields = false ; @@ -23,7 +25,7 @@ class Grid extends $pb.GeneratedMessage { factory Grid({ $core.String? id, $core.Iterable? fieldOrders, - $core.Iterable? rowOrders, + $core.Iterable<$0.GridBlockMeta>? blocks, }) { final _result = create(); if (id != null) { @@ -32,8 +34,8 @@ class Grid extends $pb.GeneratedMessage { if (fieldOrders != null) { _result.fieldOrders.addAll(fieldOrders); } - if (rowOrders != null) { - _result.rowOrders.addAll(rowOrders); + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } @@ -71,7 +73,7 @@ class Grid extends $pb.GeneratedMessage { $core.List get fieldOrders => $_getList(1); @$pb.TagNumber(3) - $core.List get rowOrders => $_getList(2); + $core.List<$0.GridBlockMeta> get blocks => $_getList(2); } class Field extends $pb.GeneratedMessage { @@ -505,15 +507,15 @@ class Row extends $pb.GeneratedMessage { void clearHeight() => clearField(3); } -class RepeatedRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) +class RepeatedGridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridBlock', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridBlock.create) ..hasRequiredFields = false ; - RepeatedRow._() : super(); - factory RepeatedRow({ - $core.Iterable? items, + RepeatedGridBlock._() : super(); + factory RepeatedGridBlock({ + $core.Iterable? items, }) { final _result = create(); if (items != null) { @@ -521,29 +523,84 @@ class RepeatedRow extends $pb.GeneratedMessage { } return _result; } - factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory RepeatedGridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedGridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); + RepeatedGridBlock clone() => RepeatedGridBlock()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use + RepeatedGridBlock copyWith(void Function(RepeatedGridBlock) updates) => super.copyWith((message) => updates(message as RepeatedGridBlock)) as RepeatedGridBlock; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static RepeatedRow create() => RepeatedRow._(); - RepeatedRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static RepeatedGridBlock create() => RepeatedGridBlock._(); + RepeatedGridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedRow? _defaultInstance; + static RepeatedGridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedGridBlock? _defaultInstance; @$pb.TagNumber(1) - $core.List get items => $_getList(0); + $core.List get items => $_getList(0); +} + +class GridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: Row.create) + ..hasRequiredFields = false + ; + + GridBlock._() : super(); + factory GridBlock({ + $core.String? blockId, + $core.Iterable? rows, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlock clone() => GridBlock()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlock create() => GridBlock._(); + GridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlock? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rows => $_getList(1); } class Cell extends $pb.GeneratedMessage { @@ -742,6 +799,53 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +class GridBlockId extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockId', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') + ..hasRequiredFields = false + ; + + GridBlockId._() : super(); + factory GridBlockId({ + $core.String? value, + }) { + final _result = create(); + if (value != null) { + _result.value = value; + } + return _result; + } + factory GridBlockId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlockId clone() => GridBlockId()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockId copyWith(void Function(GridBlockId) updates) => super.copyWith((message) => updates(message as GridBlockId)) as GridBlockId; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockId create() => GridBlockId._(); + GridBlockId createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockId? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get value => $_getSZ(0); + @$pb.TagNumber(1) + set value($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasValue() => $_has(0); + @$pb.TagNumber(1) + void clearValue() => clearField(1); +} + enum CreateRowPayload_OneOfUpperRowId { upperRowId, notSet @@ -879,47 +983,47 @@ class QueryFieldPayload extends $pb.GeneratedMessage { RepeatedFieldOrder ensureFieldOrders() => $_ensure(1); } -class QueryRowPayload extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) +class QueryGridBlocksPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryGridBlocksPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..pc<$0.GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) ..hasRequiredFields = false ; - QueryRowPayload._() : super(); - factory QueryRowPayload({ + QueryGridBlocksPayload._() : super(); + factory QueryGridBlocksPayload({ $core.String? gridId, - RepeatedRowOrder? rowOrders, + $core.Iterable<$0.GridBlockMeta>? blocks, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (rowOrders != null) { - _result.rowOrders = rowOrders; + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } - factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory QueryRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory QueryGridBlocksPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryGridBlocksPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this); + QueryGridBlocksPayload clone() => QueryGridBlocksPayload()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use + QueryGridBlocksPayload copyWith(void Function(QueryGridBlocksPayload) updates) => super.copyWith((message) => updates(message as QueryGridBlocksPayload)) as QueryGridBlocksPayload; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static QueryRowPayload create() => QueryRowPayload._(); - QueryRowPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static QueryGridBlocksPayload create() => QueryGridBlocksPayload._(); + QueryGridBlocksPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static QueryRowPayload? _defaultInstance; + static QueryGridBlocksPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryGridBlocksPayload? _defaultInstance; @$pb.TagNumber(1) $core.String get gridId => $_getSZ(0); @@ -931,14 +1035,6 @@ class QueryRowPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - RepeatedRowOrder get rowOrders => $_getN(1); - @$pb.TagNumber(2) - set rowOrders(RepeatedRowOrder v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasRowOrders() => $_has(1); - @$pb.TagNumber(2) - void clearRowOrders() => clearField(2); - @$pb.TagNumber(2) - RepeatedRowOrder ensureRowOrders() => $_ensure(1); + $core.List<$0.GridBlockMeta> get blocks => $_getList(1); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index a6a7eb79d3..97d52d827f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -14,12 +14,12 @@ const Grid$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'}, - const {'1': 'row_orders', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxImCgZibG9ja3MYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', @@ -110,16 +110,27 @@ const Row_CellByFieldIdEntry$json = const { /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); -@$core.Deprecated('Use repeatedRowDescriptor instead') -const RepeatedRow$json = const { - '1': 'RepeatedRow', +@$core.Deprecated('Use repeatedGridBlockDescriptor instead') +const RepeatedGridBlock$json = const { + '1': 'RepeatedGridBlock', '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.GridBlock', '10': 'items'}, ], }; -/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); +/// Descriptor for `RepeatedGridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedGridBlockDescriptor = $convert.base64Decode('ChFSZXBlYXRlZEdyaWRCbG9jaxIgCgVpdGVtcxgBIAMoCzIKLkdyaWRCbG9ja1IFaXRlbXM='); +@$core.Deprecated('Use gridBlockDescriptor instead') +const GridBlock$json = const { + '1': 'GridBlock', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.Row', '10': 'rows'}, + ], +}; + +/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSGAoEcm93cxgCIAMoCzIELlJvd1IEcm93cw=='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', @@ -161,6 +172,16 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use gridBlockIdDescriptor instead') +const GridBlockId$json = const { + '1': 'GridBlockId', + '2': const [ + const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, + ], +}; + +/// Descriptor for `GridBlockId`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockIdDescriptor = $convert.base64Decode('CgtHcmlkQmxvY2tJZBIUCgV2YWx1ZRgBIAEoCVIFdmFsdWU='); @$core.Deprecated('Use createRowPayloadDescriptor instead') const CreateRowPayload$json = const { '1': 'CreateRowPayload', @@ -186,14 +207,14 @@ const QueryFieldPayload$json = const { /// Descriptor for `QueryFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List queryFieldPayloadDescriptor = $convert.base64Decode('ChFRdWVyeUZpZWxkUGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSNgoMZmllbGRfb3JkZXJzGAIgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycw=='); -@$core.Deprecated('Use queryRowPayloadDescriptor instead') -const QueryRowPayload$json = const { - '1': 'QueryRowPayload', +@$core.Deprecated('Use queryGridBlocksPayloadDescriptor instead') +const QueryGridBlocksPayload$json = const { + '1': 'QueryGridBlocksPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'row_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + const {'1': 'blocks', '3': 2, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; -/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjAKCnJvd19vcmRlcnMYAiABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); +/// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBImCgZibG9ja3MYAiADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 38adc076a6..0a3cba6be6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlock.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blocks, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -73,102 +73,32 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); -} - -class GridBlock extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - GridBlock._() : super(); - factory GridBlock({ - $core.String? id, - $core.int? startRowIndex, - $core.int? rowCount, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (startRowIndex != null) { - _result.startRowIndex = startRowIndex; - } - if (rowCount != null) { - _result.rowCount = rowCount; - } - return _result; - } - factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GridBlock clone() => GridBlock()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridBlock create() => GridBlock._(); - GridBlock createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlock? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.int get startRowIndex => $_getIZ(1); - @$pb.TagNumber(2) - set startRowIndex($core.int v) { $_setSignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasStartRowIndex() => $_has(1); - @$pb.TagNumber(2) - void clearStartRowIndex() => clearField(2); - - @$pb.TagNumber(3) - $core.int get rowCount => $_getIZ(2); - @$pb.TagNumber(3) - set rowCount($core.int v) { $_setSignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasRowCount() => $_has(2); - @$pb.TagNumber(3) - void clearRowCount() => clearField(3); + $core.List get blocks => $_getList(2); } class GridBlockMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) ..hasRequiredFields = false ; GridBlockMeta._() : super(); factory GridBlockMeta({ $core.String? blockId, - $core.Iterable? rows, + $core.int? startRowIndex, + $core.int? rowCount, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rows != null) { - _result.rows.addAll(rows); + if (startRowIndex != null) { + _result.startRowIndex = startRowIndex; + } + if (rowCount != null) { + _result.rowCount = rowCount; } return _result; } @@ -203,7 +133,77 @@ class GridBlockMeta extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List get rows => $_getList(1); + $core.int get startRowIndex => $_getIZ(1); + @$pb.TagNumber(2) + set startRowIndex($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasStartRowIndex() => $_has(1); + @$pb.TagNumber(2) + void clearStartRowIndex() => clearField(2); + + @$pb.TagNumber(3) + $core.int get rowCount => $_getIZ(2); + @$pb.TagNumber(3) + set rowCount($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowCount() => $_has(2); + @$pb.TagNumber(3) + void clearRowCount() => clearField(3); +} + +class GridBlockMetaData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + GridBlockMetaData._() : super(); + factory GridBlockMetaData({ + $core.String? blockId, + $core.Iterable? rowMetas, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (rowMetas != null) { + _result.rowMetas.addAll(rowMetas); + } + return _result; + } + factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockMetaData create() => GridBlockMetaData._(); + GridBlockMetaData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMetaData? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rowMetas => $_getList(1); } class FieldMeta extends $pb.GeneratedMessage { @@ -1020,16 +1020,16 @@ class CellMetaChangeset extends $pb.GeneratedMessage { class BuildGridContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlock.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMeta', subBuilder: GridBlockMeta.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlockMeta.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMetaData', subBuilder: GridBlockMetaData.create) ..hasRequiredFields = false ; BuildGridContext._() : super(); factory BuildGridContext({ $core.Iterable? fieldMetas, - GridBlock? gridBlock, - GridBlockMeta? gridBlockMeta, + GridBlockMeta? gridBlock, + GridBlockMetaData? gridBlockMetaData, }) { final _result = create(); if (fieldMetas != null) { @@ -1038,8 +1038,8 @@ class BuildGridContext extends $pb.GeneratedMessage { if (gridBlock != null) { _result.gridBlock = gridBlock; } - if (gridBlockMeta != null) { - _result.gridBlockMeta = gridBlockMeta; + if (gridBlockMetaData != null) { + _result.gridBlockMetaData = gridBlockMetaData; } return _result; } @@ -1068,25 +1068,25 @@ class BuildGridContext extends $pb.GeneratedMessage { $core.List get fieldMetas => $_getList(0); @$pb.TagNumber(2) - GridBlock get gridBlock => $_getN(1); + GridBlockMeta get gridBlock => $_getN(1); @$pb.TagNumber(2) - set gridBlock(GridBlock v) { setField(2, v); } + set gridBlock(GridBlockMeta v) { setField(2, v); } @$pb.TagNumber(2) $core.bool hasGridBlock() => $_has(1); @$pb.TagNumber(2) void clearGridBlock() => clearField(2); @$pb.TagNumber(2) - GridBlock ensureGridBlock() => $_ensure(1); + GridBlockMeta ensureGridBlock() => $_ensure(1); @$pb.TagNumber(3) - GridBlockMeta get gridBlockMeta => $_getN(2); + GridBlockMetaData get gridBlockMetaData => $_getN(2); @$pb.TagNumber(3) - set gridBlockMeta(GridBlockMeta v) { setField(3, v); } + set gridBlockMetaData(GridBlockMetaData v) { setField(3, v); } @$pb.TagNumber(3) - $core.bool hasGridBlockMeta() => $_has(2); + $core.bool hasGridBlockMetaData() => $_has(2); @$pb.TagNumber(3) - void clearGridBlockMeta() => clearField(3); + void clearGridBlockMetaData() => clearField(3); @$pb.TagNumber(3) - GridBlockMeta ensureGridBlockMeta() => $_ensure(2); + GridBlockMetaData ensureGridBlockMetaData() => $_ensure(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 7ce08c0a9d..7048fb3c81 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,35 +29,35 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlock', '10': 'blocks'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSIgoGYmxvY2tzGAMgAygLMgouR3JpZEJsb2NrUgZibG9ja3M='); -@$core.Deprecated('Use gridBlockDescriptor instead') -const GridBlock$json = const { - '1': 'GridBlock', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, - const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, - ], -}; - -/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz'); @$core.Deprecated('Use gridBlockMetaDescriptor instead') const GridBlockMeta$json = const { '1': 'GridBlockMeta', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, + const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, ], }; /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); +final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); +@$core.Deprecated('Use gridBlockMetaDataDescriptor instead') +const GridBlockMetaData$json = const { + '1': 'GridBlockMetaData', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'}, + ], +}; + +/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw=='); @$core.Deprecated('Use fieldMetaDescriptor instead') const FieldMeta$json = const { '1': 'FieldMeta', @@ -197,10 +197,10 @@ const BuildGridContext$json = const { '1': 'BuildGridContext', '2': const [ const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, - const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlock', '10': 'gridBlock'}, - const {'1': 'grid_block_meta', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlockMeta'}, + const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlock'}, + const {'1': 'grid_block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'gridBlockMetaData'}, ], }; /// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEikKCmdyaWRfYmxvY2sYAiABKAsyCi5HcmlkQmxvY2tSCWdyaWRCbG9jaxI2Cg9ncmlkX2Jsb2NrX21ldGEYAyABKAsyDi5HcmlkQmxvY2tNZXRhUg1ncmlkQmxvY2tNZXRh'); +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmdyaWRfYmxvY2sYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglncmlkQmxvY2sSQwoUZ3JpZF9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVIRZ3JpZEJsb2NrTWV0YURhdGE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 9f4245122f..54f33ea020 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -11,17 +11,13 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); - static const GridNotification GridDidCreateRows = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateRows'); - static const GridNotification GridDidDeleteRow = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidDeleteRow'); - static const GridNotification GridDidUpdateRows = GridNotification._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateRows'); + static const GridNotification GridDidUpdateBlock = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateBlock'); static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); static const $core.List values = [ Unknown, - GridDidCreateRows, - GridDidDeleteRow, - GridDidUpdateRows, + GridDidUpdateBlock, GridDidUpdateCells, GridDidUpdateFields, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 5100550835..4c4ff69eb1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -13,13 +13,11 @@ const GridNotification$json = const { '1': 'GridNotification', '2': const [ const {'1': 'Unknown', '2': 0}, - const {'1': 'GridDidCreateRows', '2': 10}, - const {'1': 'GridDidDeleteRow', '2': 11}, - const {'1': 'GridDidUpdateRows', '2': 12}, + const {'1': 'GridDidUpdateBlock', '2': 10}, const {'1': 'GridDidUpdateCells', '2': 20}, const {'1': 'GridDidUpdateFields', '2': 30}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIVChFHcmlkRGlkQ3JlYXRlUm93cxAKEhQKEEdyaWREaWREZWxldGVSb3cQCxIVChFHcmlkRGlkVXBkYXRlUm93cxAMEhYKEkdyaWREaWRVcGRhdGVDZWxscxAUEhcKE0dyaWREaWRVcGRhdGVGaWVsZHMQHg=='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index ac47fe4a51..787f44e52c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -11,14 +11,14 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetGridData = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridData'); - static const GridEvent GetRows = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows'); + static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks'); static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, - GetRows, + GetGridBlocks, GetFields, CreateRow, UpdateCell, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 145521943a..707eca7c61 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -13,7 +13,7 @@ const GridEvent$json = const { '1': 'GridEvent', '2': const [ const {'1': 'GetGridData', '2': 0}, - const {'1': 'GetRows', '2': 1}, + const {'1': 'GetGridBlocks', '2': 1}, const {'1': 'GetFields', '2': 2}, const {'1': 'CreateRow', '2': 3}, const {'1': 'UpdateCell', '2': 4}, @@ -21,4 +21,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index d6fb15d719..ba0396bf7f 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -5,9 +5,7 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; #[derive(ProtoBuf_Enum, Debug)] pub enum GridNotification { Unknown = 0, - GridDidCreateRows = 10, - GridDidDeleteRow = 11, - GridDidUpdateRows = 12, + GridDidUpdateBlock = 10, GridDidUpdateCells = 20, GridDidUpdateFields = 30, diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 9d0001305d..8921d15aea 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,8 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, - RepeatedRow, Row, + CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, RepeatedField, + RepeatedGridBlock, Row, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -19,14 +19,14 @@ pub(crate) async fn get_grid_data_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn get_rows_handler( - data: Data, +pub(crate) async fn get_grid_blocks_handler( + data: Data, manager: AppData>, -) -> DataResult { - let payload: QueryRowPayload = data.into_inner(); +) -> DataResult { + let payload: QueryGridBlocksPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); - data_result(repeated_row) + let repeated_grid_block = editor.get_grid_blocks(Some(payload.blocks)).await?; + data_result(repeated_grid_block) } #[tracing::instrument(level = "debug", skip(data, manager), err)] diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 6adc06e709..d748b3b882 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -9,7 +9,7 @@ pub fn create(grid_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager); module = module .event(GridEvent::GetGridData, get_grid_data_handler) - .event(GridEvent::GetRows, get_rows_handler) + .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); @@ -23,8 +23,8 @@ pub enum GridEvent { #[event(input = "GridId", output = "Grid")] GetGridData = 0, - #[event(input = "QueryRowPayload", output = "RepeatedRow")] - GetRows = 1, + #[event(input = "QueryGridBlocksPayload", output = "RepeatedGridBlock")] + GetGridBlocks = 1, #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 2, diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index fde6d136f2..7afcdf05fd 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -182,7 +182,7 @@ pub async fn make_grid_view_data( grid_manager: Arc, build_context: BuildGridContext, ) -> FlowyResult { - let block_id = build_context.grid_block.id.clone(); + let block_id = build_context.grid_block.block_id.clone(); let grid_meta = GridMeta { grid_id: view_id.to_string(), fields: build_context.field_metas, @@ -195,7 +195,7 @@ pub async fn make_grid_view_data( Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); let _ = grid_manager.create_grid(view_id, repeated_revision).await?; - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into(); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 63676bd6e6..a4f7fbb46c 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -26,9 +26,7 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridNotification { Unknown = 0, - GridDidCreateRows = 10, - GridDidDeleteRow = 11, - GridDidUpdateRows = 12, + GridDidUpdateBlock = 10, GridDidUpdateCells = 20, GridDidUpdateFields = 30, } @@ -41,9 +39,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), - 10 => ::std::option::Option::Some(GridNotification::GridDidCreateRows), - 11 => ::std::option::Option::Some(GridNotification::GridDidDeleteRow), - 12 => ::std::option::Option::Some(GridNotification::GridDidUpdateRows), + 10 => ::std::option::Option::Some(GridNotification::GridDidUpdateBlock), 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), _ => ::std::option::Option::None @@ -53,9 +49,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn values() -> &'static [Self] { static values: &'static [GridNotification] = &[ GridNotification::Unknown, - GridNotification::GridDidCreateRows, - GridNotification::GridDidDeleteRow, - GridNotification::GridDidUpdateRows, + GridNotification::GridDidUpdateBlock, GridNotification::GridDidUpdateCells, GridNotification::GridDidUpdateFields, ]; @@ -86,11 +80,9 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x94\x01\n\x10GridNotification\x12\x0b\n\ - \x07Unknown\x10\0\x12\x15\n\x11GridDidCreateRows\x10\n\x12\x14\n\x10Grid\ - DidDeleteRow\x10\x0b\x12\x15\n\x11GridDidUpdateRows\x10\x0c\x12\x16\n\ - \x12GridDidUpdateCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\ - \x06proto3\ + \n\x17dart_notification.proto*h\n\x10GridNotification\x12\x0b\n\x07Unkno\ + wn\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12GridDidUpdat\ + eCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 028f37bab5..1ed38366d4 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -26,7 +26,7 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridEvent { GetGridData = 0, - GetRows = 1, + GetGridBlocks = 1, GetFields = 2, CreateRow = 3, UpdateCell = 4, @@ -40,7 +40,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(GridEvent::GetGridData), - 1 => ::std::option::Option::Some(GridEvent::GetRows), + 1 => ::std::option::Option::Some(GridEvent::GetGridBlocks), 2 => ::std::option::Option::Some(GridEvent::GetFields), 3 => ::std::option::Option::Some(GridEvent::CreateRow), 4 => ::std::option::Option::Some(GridEvent::UpdateCell), @@ -51,7 +51,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn values() -> &'static [Self] { static values: &'static [GridEvent] = &[ GridEvent::GetGridData, - GridEvent::GetRows, + GridEvent::GetGridBlocks, GridEvent::GetFields, GridEvent::CreateRow, GridEvent::UpdateCell, @@ -83,9 +83,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*W\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ - \x0b\n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\ - \x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\ + \n\x0fevent_map.proto*]\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ + \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreate\ + Row\x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 9c606ac091..9aadc14372 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -2,9 +2,7 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; - GridDidCreateRows = 10; - GridDidDeleteRow = 11; - GridDidUpdateRows = 12; + GridDidUpdateBlock = 10; GridDidUpdateCells = 20; GridDidUpdateFields = 30; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index e06c2e56b3..a5c998e7e1 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -2,7 +2,7 @@ syntax = "proto3"; enum GridEvent { GetGridData = 0; - GetRows = 1; + GetGridBlocks = 1; GetFields = 2; CreateRow = 3; UpdateCell = 4; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 8e49a47588..21046c295c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,14 +1,14 @@ use crate::manager::GridUser; -use crate::services::row::{make_cell, make_row_ids_per_block, make_rows}; +use crate::services::row::{make_cell, make_grid_blocks, make_row_ids_per_block, GridBlockMetaDataSnapshot}; use bytes::Bytes; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; +use flowy_collaboration::client_grid::{GridBlockMetaDataChange, GridBlockMetaDataPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, FieldMeta, GridBlock, GridBlockChangeset, RepeatedCell, RepeatedRow, RepeatedRowOrder, RowMeta, + Cell, FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -30,12 +30,12 @@ type BlockId = String; pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, - editor_map: DashMap>, + editor_map: DashMap>, block_id_by_row_id: DashMap, } impl GridBlockMetaEditorManager { - pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { + pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); let block_id_by_row_id = DashMap::new(); @@ -49,7 +49,7 @@ impl GridBlockMetaEditorManager { Ok(manager) } - pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { match self.editor_map.get(block_id) { None => { tracing::error!("The is a fatal error, block is not exist"); @@ -63,29 +63,22 @@ impl GridBlockMetaEditorManager { pub(crate) async fn create_row( &self, - field_metas: &[FieldMeta], + block_id: &str, row_meta: RowMeta, - upper_row_id: Option, + start_row_id: Option, ) -> FlowyResult { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); let editor = self.get_editor(&row_meta.block_id).await?; - - let rows = make_rows(field_metas, vec![row_meta.clone().into()]); - send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) - .payload(RepeatedRow::from(rows)) - .send(); - - self.notify_did_create_rows(field_metas, vec![row_meta.clone()]); - - editor.create_row(row_meta, upper_row_id).await + let row_count = editor.create_row(row_meta, start_row_id).await?; + self.notify_did_update_block(block_id).await?; + Ok(row_count) } pub(crate) async fn insert_row( &self, - field_metas: &[FieldMeta], rows_by_block_id: HashMap>, - ) -> FlowyResult> { + ) -> FlowyResult> { let mut changesets = vec![]; for (block_id, row_metas) in rows_by_block_id { let editor = self.get_editor(&block_id).await?; @@ -94,14 +87,14 @@ impl GridBlockMetaEditorManager { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); row_count = editor.create_row(row.clone(), None).await?; } - changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); - self.notify_did_create_rows(field_metas, row_metas); + changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); + let _ = self.notify_did_update_block(&block_id).await?; } Ok(changesets) } - pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { let row_orders = row_ids .into_iter() .flat_map(|row_id| { @@ -117,7 +110,7 @@ impl GridBlockMetaEditorManager { let editor = self.get_editor(&row_ids_per_block.block_id).await?; let row_count = editor.delete_rows(row_ids_per_block.row_ids).await?; - let changeset = GridBlockChangeset::from_row_count(&row_ids_per_block.block_id, row_count); + let changeset = GridBlockMetaChangeset::from_row_count(&row_ids_per_block.block_id, row_count); changesets.push(changeset); } @@ -127,7 +120,7 @@ impl GridBlockMetaEditorManager { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - let _ = self.notify_did_update_row()?; + let _ = self.notify_did_update_block(&editor.block_id).await?; Ok(()) } @@ -138,48 +131,58 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult>> { - let mut row_metas = vec![]; + pub(crate) async fn get_block_meta_snapshot_from_blocks( + &self, + grid_blocks: Vec, + ) -> FlowyResult> { + let mut snapshots = vec![]; for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.id).await?; - let new_row_metas = editor.get_row_metas(None).await?; - new_row_metas.iter().for_each(|row_meta| { + let editor = self.get_editor(&grid_block.block_id).await?; + let row_metas = editor.get_row_metas(None).await?; + row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - row_metas.extend(new_row_metas); + snapshots.push(GridBlockMetaDataSnapshot { + block_id: grid_block.block_id, + row_metas, + }); } - Ok(row_metas) + Ok(snapshots) } - pub(crate) async fn get_row_orders(&self, grid_blocks: Vec) -> FlowyResult> { - let mut row_orders = vec![]; - for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.id).await?; + pub(crate) async fn get_block_meta_snapshot_from_row_orders( + &self, + grid_block_metas: &Vec, + ) -> FlowyResult> { + let mut snapshots = vec![]; + for grid_block_meta in grid_block_metas { + let editor = self.get_editor(&grid_block_meta.block_id).await?; let row_metas = editor.get_row_metas(None).await?; - let block_row_orders = row_metas.iter().map(RowOrder::from); - row_orders.extend(block_row_orders); + row_metas.iter().for_each(|row_meta| { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + }); + snapshots.push(GridBlockMetaDataSnapshot { + block_id: grid_block_meta.block_id.clone(), + row_metas, + }); + } + Ok(snapshots) + } + + pub(crate) async fn get_row_orders(&self, grid_block_ids: Vec) -> FlowyResult> { + let mut row_orders = vec![]; + for grid_block_id in grid_block_ids { + let editor = self.get_editor(&grid_block_id).await?; + let new_row_order = editor.get_row_orders().await?; + row_orders.extend(new_row_order); } Ok(row_orders) } - pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult>> { - let row_ids_per_blocks = make_row_ids_per_block(row_orders); - let mut row_metas = vec![]; - for row_ids_per_block in row_ids_per_blocks { - let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let new_row_metas = editor.get_row_metas(Some(row_ids_per_block.row_ids)).await?; - new_row_metas.iter().for_each(|row_meta| { - self.block_id_by_row_id - .insert(row_meta.id.clone(), row_meta.block_id.clone()); - }); - row_metas.extend(new_row_metas); - } - Ok(row_metas) - } - - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { match self.block_id_by_row_id.get(row_id) { None => { let msg = format!( @@ -195,25 +198,14 @@ impl GridBlockMetaEditorManager { } } - fn notify_did_create_rows(&self, field_metas: &[FieldMeta], row_metas: Vec) { - let rows = make_rows( - field_metas, - row_metas - .into_iter() - .map(|row_meta| Arc::new(row_meta)) - .collect::>(), - ); - send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) - .payload(RepeatedRow::from(rows)) + async fn notify_did_update_block(&self, block_id: &str) -> FlowyResult<()> { + let block_id = GridBlockId { + value: block_id.to_owned(), + }; + send_dart_notification(&self.grid_id, GridNotification::GridDidUpdateBlock) + .payload(block_id) .send(); - } - - fn notify_did_update_row(&self) -> FlowyResult<()> { - // send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateRows) - // .payload(RepeatedRow::from(cells)) - // .send(); - - todo!() + Ok(()) } fn notify_did_update_cells(&self, changeset: RowMetaChangeset, field_metas: &[FieldMeta]) -> FlowyResult<()> { @@ -244,18 +236,21 @@ impl GridBlockMetaEditorManager { async fn make_block_meta_editor_map( user: &Arc, - blocks: Vec, -) -> FlowyResult>> { + blocks: Vec, +) -> FlowyResult>> { let editor_map = DashMap::new(); for block in blocks { - let editor = make_block_meta_editor(user, &block.id).await?; - editor_map.insert(block.id, Arc::new(editor)); + let editor = make_block_meta_editor(user, &block.block_id).await?; + editor_map.insert(block.block_id, Arc::new(editor)); } Ok(editor_map) } -async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { +async fn make_block_meta_editor( + user: &Arc, + block_id: &str, +) -> FlowyResult { let token = user.token()?; let user_id = user.user_id()?; let pool = user.db_pool()?; @@ -263,17 +258,17 @@ async fn make_block_meta_editor(user: &Arc, block_id: &str) -> Flo let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache)); let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence); - ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await + ClientGridBlockMetaDataEditor::new(&user_id, &token, block_id, rev_manager).await } -pub struct ClientGridBlockMetaEditor { +pub struct ClientGridBlockMetaDataEditor { user_id: String, pub block_id: String, - meta_pad: Arc>, + pad: Arc>, rev_manager: Arc, } -impl ClientGridBlockMetaEditor { +impl ClientGridBlockMetaDataEditor { pub async fn new( user_id: &str, token: &str, @@ -284,23 +279,23 @@ impl ClientGridBlockMetaEditor { token: token.to_owned(), }); let block_meta_pad = rev_manager.load::(Some(cloud)).await?; - let meta_pad = Arc::new(RwLock::new(block_meta_pad)); + let pad = Arc::new(RwLock::new(block_meta_pad)); let rev_manager = Arc::new(rev_manager); let user_id = user_id.to_owned(); let block_id = block_id.to_owned(); Ok(Self { user_id, block_id, - meta_pad, + pad, rev_manager, }) } - async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { + async fn create_row(&self, row: RowMeta, start_row_id: Option) -> FlowyResult { let mut row_count = 0; let _ = self .modify(|pad| { - let change = pad.add_row(row, upper_row_id)?; + let change = pad.add_row(row, start_row_id)?; row_count = pad.number_of_rows(); Ok(change) }) @@ -327,13 +322,13 @@ impl ClientGridBlockMetaEditor { } pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { - let row_metas = self.meta_pad.read().await.get_rows(row_ids)?; + let row_metas = self.pad.read().await.get_rows(row_ids)?; Ok(row_metas) } pub async fn get_row_orders(&self) -> FlowyResult> { let row_orders = self - .meta_pad + .pad .read() .await .get_rows(None)? @@ -345,9 +340,9 @@ impl ClientGridBlockMetaEditor { async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridBlockMetaDataPad) -> FlowyResult>, { - let mut write_guard = self.meta_pad.write().await; + let mut write_guard = self.pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -357,8 +352,8 @@ impl ClientGridBlockMetaEditor { Ok(()) } - async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> { - let GridBlockMetaChange { delta, md5 } = change; + async fn apply_change(&self, change: GridBlockMetaDataChange) -> FlowyResult<()> { + let GridBlockMetaDataChange { delta, md5 } = change; let user_id = self.user_id.clone(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let delta_data = delta.to_delta_bytes(); @@ -392,10 +387,10 @@ impl RevisionCloudService for GridBlockMetaRevisionCloudService { struct GridBlockMetaPadBuilder(); impl RevisionObjectBuilder for GridBlockMetaPadBuilder { - type Output = GridBlockMetaPad; + type Output = GridBlockMetaDataPad; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?; + let pad = GridBlockMetaDataPad::from_revisions(object_id, revisions)?; Ok(pad) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 491a2831bb..f991d26a10 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -6,14 +6,15 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedField, - RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, + Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, + RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ - make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder, + make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, row_meta_from_context, + serialize_cell_data, GridBlockMetaDataSnapshot, RowMetaContext, RowMetaContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -24,7 +25,7 @@ use tokio::sync::RwLock; pub struct ClientGridEditor { grid_id: String, user: Arc, - grid_meta_pad: Arc>, + pad: Arc>, rev_manager: Arc, block_meta_manager: Arc, } @@ -39,16 +40,15 @@ impl ClientGridEditor { let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); - let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); + let pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = Arc::new( - GridBlockMetaEditorManager::new(grid_id, &user, grid_meta_pad.read().await.get_blocks().clone()).await?, - ); + let block_meta_manager = + Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, pad.read().await.get_blocks().clone()).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, - grid_meta_pad, + pad, rev_manager, block_meta_manager, })) @@ -61,7 +61,7 @@ impl ClientGridEditor { } pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool { - self.grid_meta_pad.read().await.contain_field(&field_meta.id) + self.pad.read().await.contain_field(&field_meta.id) } pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { @@ -74,19 +74,19 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_block(&self, grid_block: GridBlock) -> FlowyResult<()> { + pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; Ok(()) } - pub async fn update_block(&self, changeset: GridBlockChangeset) -> FlowyResult<()> { + pub async fn update_block(&self, changeset: GridBlockMetaChangeset) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?; Ok(()) } - pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult<()> { - let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; - let block_id = self.last_block_id().await?; + pub async fn create_row(&self, start_row_id: Option) -> FlowyResult<()> { + let field_metas = self.pad.read().await.get_field_metas(None)?; + let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build(); @@ -95,18 +95,17 @@ impl ClientGridEditor { // insert the row let row_count = self .block_meta_manager - .create_row(&field_metas, row_meta, upper_row_id) + .create_row(&block_id, row_meta, start_row_id) .await?; // update block row count - let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); + let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; Ok(()) } pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { - let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; - let block_id = self.last_block_id().await?; + let block_id = self.block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); for ctx in contexts { let row_meta = row_meta_from_context(&block_id, ctx); @@ -115,10 +114,7 @@ impl ClientGridEditor { .or_insert_with(Vec::new) .push(row_meta); } - let changesets = self - .block_meta_manager - .insert_row(&field_metas, rows_by_block_id) - .await?; + let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } @@ -131,7 +127,7 @@ impl ClientGridEditor { pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { if let Some(cell_data) = changeset.data.as_ref() { - match self.grid_meta_pad.read().await.get_field(&changeset.field_id) { + match self.pad.read().await.get_field(&changeset.field_id) { None => { return Err(FlowyError::internal() .context(format!("Can not find the field with id: {}", &changeset.field_id))); @@ -151,32 +147,39 @@ impl ClientGridEditor { Ok(()) } - pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { - let row_metas = self.get_row_metas(row_orders.as_ref()).await?; - let field_meta = self.grid_meta_pad.read().await.get_field_metas(None)?; - match row_orders { - None => Ok(make_rows(&field_meta, row_metas)), - Some(row_orders) => { - let mut row_map: HashMap = make_row_by_row_id(&field_meta, row_metas); - let rows = row_orders - .iter() - .flat_map(|row_order| row_map.remove(&row_order.row_id)) - .collect::>(); - Ok(rows) + pub async fn get_grid_blocks( + &self, + grid_block_metas: Option>, + ) -> FlowyResult { + let grid_block_meta_snapshots = self.get_grid_block_meta_snapshots(grid_block_metas.as_ref()).await?; + let field_meta = self.pad.read().await.get_field_metas(None)?; + match grid_block_metas { + None => make_grid_blocks(&field_meta, grid_block_meta_snapshots), + Some(grid_block_metas) => { + make_grid_block_from_block_metas(&field_meta, grid_block_metas, grid_block_meta_snapshots) } } } - pub async fn get_row_metas(&self, row_orders: Option<&RepeatedRowOrder>) -> FlowyResult>> { - match row_orders { + pub(crate) async fn get_grid_block_meta_snapshots( + &self, + grid_block_infos: Option<&Vec>, + ) -> FlowyResult> { + match grid_block_infos { None => { - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); - let row_metas = self.block_meta_manager.get_all_rows(grid_blocks).await?; - Ok(row_metas) + let grid_blocks = self.pad.read().await.get_blocks(); + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_snapshot_from_blocks(grid_blocks) + .await?; + Ok(row_metas_per_block) } - Some(row_orders) => { - let row_metas = self.block_meta_manager.get_rows(row_orders).await?; - Ok(row_metas) + Some(grid_block_infos) => { + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_snapshot_from_row_orders(grid_block_infos) + .await?; + Ok(row_metas_per_block) } } } @@ -190,35 +193,34 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> FlowyResult { - let field_orders = self.grid_meta_pad.read().await.get_field_orders(); - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); - let row_orders = self.block_meta_manager.get_row_orders(grid_blocks).await?; + let field_orders = self.pad.read().await.get_field_orders(); + let block_orders = self.pad.read().await.get_blocks(); Ok(Grid { id: self.grid_id.clone(), field_orders, - row_orders, + blocks: block_orders, }) } pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { - let field_meta = self.grid_meta_pad.read().await.get_field_metas(field_orders)?; + let field_meta = self.pad.read().await.get_field_metas(field_orders)?; Ok(field_meta) } - pub async fn get_blocks(&self) -> FlowyResult> { - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + pub async fn get_blocks(&self) -> FlowyResult> { + let grid_blocks = self.pad.read().await.get_blocks(); Ok(grid_blocks) } pub async fn delta_bytes(&self) -> Bytes { - self.grid_meta_pad.read().await.delta_bytes() + self.pad.read().await.delta_bytes() } async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { - let mut write_guard = self.grid_meta_pad.write().await; + let mut write_guard = self.pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -248,10 +250,10 @@ impl ClientGridEditor { Ok(()) } - async fn last_block_id(&self) -> FlowyResult { - match self.grid_meta_pad.read().await.get_blocks().last() { + async fn block_id(&self) -> FlowyResult { + match self.pad.read().await.get_blocks().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => Ok(grid_block.id.clone()), + Some(grid_block) => Ok(grid_block.block_id.clone()), } } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 6283db0540..953a950917 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,5 +1,8 @@ use crate::services::row::deserialize_cell_data; -use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder}; +use flowy_error::FlowyResult; +use flowy_grid_data_model::entities::{ + Cell, CellMeta, FieldMeta, GridBlock, GridBlockMeta, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, +}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::ops::Deref; @@ -10,41 +13,48 @@ pub(crate) struct RowIdsPerBlock { pub(crate) row_ids: Vec, } -pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { - let mut map: HashMap = HashMap::new(); - row_orders.iter().for_each(|row_order| { - let block_id = row_order.block_id.clone(); - let entry = map.entry(block_id.clone()).or_insert(RowIdsPerBlock { - block_id, +impl RowIdsPerBlock { + pub fn new(block_id: &str) -> Self { + RowIdsPerBlock { + block_id: block_id.to_owned(), row_ids: vec![], - }); - entry.row_ids.push(row_order.row_id.clone()); + } + } +} + +pub(crate) struct GridBlockMetaDataSnapshot { + pub(crate) block_id: String, + pub(crate) row_metas: Vec>, +} + +pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { + let mut map: HashMap<&String, RowIdsPerBlock> = HashMap::new(); + row_orders.iter().for_each(|row_order| { + let block_id = &row_order.block_id; + let row_id = row_order.row_id.clone(); + map.entry(&block_id) + .or_insert_with(|| RowIdsPerBlock::new(&block_id)) + .row_ids + .push(row_id); }); map.into_values().collect::>() } -pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec>) -> Vec { - let field_map = fields - .iter() - .map(|field| (&field.id, field)) - .collect::>(); - - let make_row = |row_meta: Arc| { - let cell_by_field_id = row_meta - .cell_by_field_id - .clone() - .into_par_iter() - .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) - .collect::>(); - - Row { - id: row_meta.id.clone(), - cell_by_field_id, - height: row_meta.height, - } - }; - - row_metas.into_iter().map(make_row).collect::>() +pub(crate) fn make_grid_blocks( + field_metas: &[FieldMeta], + grid_block_meta_snapshots: Vec, +) -> FlowyResult { + Ok(grid_block_meta_snapshots + .into_iter() + .map(|row_metas_per_block| { + let rows = make_rows_from_row_metas(field_metas, &row_metas_per_block.row_metas); + GridBlock { + block_id: row_metas_per_block.block_id, + rows, + } + }) + .collect::>() + .into()) } #[inline(always)] @@ -66,13 +76,13 @@ pub fn make_cell( } } -pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>) -> HashMap { +pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>) -> Vec { let field_meta_map = fields .iter() .map(|field_meta| (&field_meta.id, field_meta)) .collect::>(); - let make_row = |row_meta: Arc| { + let make_row = |row_meta: &Arc| { let cell_by_field_id = row_meta .cell_by_field_id .clone() @@ -80,16 +90,36 @@ pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>(); - let row = Row { + Row { id: row_meta.id.clone(), cell_by_field_id, height: row_meta.height, - }; - (row.id.clone(), row) + } }; - row_metas - .into_par_iter() - .map(make_row) - .collect::>() + row_metas.into_iter().map(make_row).collect::>() +} + +pub(crate) fn make_grid_block_from_block_metas( + field_metas: &[FieldMeta], + grid_block_metas: Vec, + grid_block_meta_snapshots: Vec, +) -> FlowyResult { + let block_meta_snapshot_map: HashMap<&String, &Vec>> = grid_block_meta_snapshots + .iter() + .map(|snapshot| (&snapshot.block_id, &snapshot.row_metas)) + .collect(); + + let mut grid_blocks = vec![]; + for grid_block_meta in grid_block_metas { + match block_meta_snapshot_map.get(&grid_block_meta.block_id) { + None => {} + Some(row_metas) => { + let rows = make_rows_from_row_metas(&field_metas, row_metas); + grid_blocks.push(GridBlock::new(&grid_block_meta.block_id, rows)); + } + } + } + + Ok(grid_blocks.into()) } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 36c202f335..dcc077be35 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,7 +4,7 @@ use chrono::NaiveDateTime; use flowy_grid::services::cell::*; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, RowMetaContextBuilder}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset, + CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, }; #[tokio::test] @@ -135,7 +135,7 @@ async fn grid_delete_field() { #[tokio::test] async fn grid_create_block() { - let grid_block = GridBlock::new(); + let grid_block = GridBlockMeta::new(); let scripts = vec![ AssertBlockCount(1), CreateBlock { block: grid_block }, @@ -146,10 +146,10 @@ async fn grid_create_block() { #[tokio::test] async fn grid_update_block() { - let grid_block = GridBlock::new(); + let grid_block = GridBlockMeta::new(); let mut cloned_grid_block = grid_block.clone(); - let changeset = GridBlockChangeset { - block_id: grid_block.id.clone(), + let changeset = GridBlockMetaChangeset { + block_id: grid_block.block_id.clone(), start_row_index: Some(2), row_count: Some(10), }; @@ -377,7 +377,7 @@ async fn grid_cell_update() { assert_eq!(row_metas.len(), 3); assert_eq!(grid_blocks.len(), 1); - let block_id = &grid_blocks.first().unwrap().id; + let block_id = &grid_blocks.first().unwrap().block_id; let mut scripts = vec![]; for (index, row_meta) in row_metas.iter().enumerate() { for field_meta in field_metas { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 6449d09f6f..20164bca37 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -6,8 +6,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::RowMetaContext; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, - RowMetaChangeset, + BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, + RowMeta, RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -33,10 +33,10 @@ pub enum EditorScript { field_meta: FieldMeta, }, CreateBlock { - block: GridBlock, + block: GridBlockMeta, }, UpdateBlock { - changeset: GridBlockChangeset, + changeset: GridBlockMetaChangeset, }, AssertBlockCount(usize), AssertBlock { @@ -46,7 +46,7 @@ pub enum EditorScript { }, AssertBlockEqual { block_index: usize, - block: GridBlock, + block: GridBlockMeta, }, CreateEmptyRow, CreateRow { @@ -75,7 +75,7 @@ pub struct GridEditorTest { pub grid_id: String, pub editor: Arc, pub field_metas: Vec, - pub grid_blocks: Vec, + pub grid_blocks: Vec, pub row_metas: Vec>, pub field_count: usize, } @@ -90,7 +90,7 @@ impl GridEditorTest { let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let field_metas = editor.get_field_metas(None).await.unwrap(); let grid_blocks = editor.get_blocks().await.unwrap(); - let row_metas = editor.get_row_metas(None).await.unwrap(); + let row_metas = editor.get_grid_block_meta_snapshots(None).await.unwrap(); let grid_id = test.view.id; Self { @@ -173,18 +173,18 @@ impl GridEditorTest { } EditorScript::CreateEmptyRow => { self.editor.create_row(None).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::CreateRow { context } => { self.editor.insert_rows(vec![context]).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { self.editor.delete_rows(row_ids).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::AssertRow { changeset } => { @@ -204,11 +204,11 @@ impl GridEditorTest { assert!(result.is_err()) } else { let _ = result.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); } } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_grid_blocks(None).await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs similarity index 85% rename from shared-lib/flowy-collaboration/src/client_grid/block_pad.rs rename to shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs index c1673259e9..dd62c787d3 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{GridBlockMetaData, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; @@ -12,7 +12,7 @@ pub type GridBlockMetaDelta = PlainTextDelta; pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GridBlockMetaPad { +pub struct GridBlockMetaDataPad { block_id: String, rows: Vec>, @@ -20,14 +20,18 @@ pub struct GridBlockMetaPad { pub(crate) delta: GridBlockMetaDelta, } -impl GridBlockMetaPad { +impl GridBlockMetaDataPad { pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_meta: GridBlockMeta = serde_json::from_str(&s).map_err(|e| { + let block_meta: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) })?; let block_id = block_meta.block_id; - let rows = block_meta.rows.into_iter().map(Arc::new).collect::>>(); + let rows = block_meta + .row_metas + .into_iter() + .map(Arc::new) + .collect::>>(); Ok(Self { block_id, rows, delta }) } @@ -39,10 +43,10 @@ impl GridBlockMetaPad { pub fn add_row( &mut self, row: RowMeta, - upper_row_id: Option, - ) -> CollaborateResult> { + start_row_id: Option, + ) -> CollaborateResult> { self.modify(|rows| { - if let Some(upper_row_id) = upper_row_id { + if let Some(upper_row_id) = start_row_id { if upper_row_id.is_empty() { rows.insert(0, Arc::new(row)); return Ok(Some(())); @@ -59,7 +63,7 @@ impl GridBlockMetaPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify(|rows| { rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) @@ -94,7 +98,7 @@ impl GridBlockMetaPad { self.rows.len() as i32 } - pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { let mut is_changed = None; @@ -119,7 +123,7 @@ impl GridBlockMetaPad { }) } - pub fn modify(&mut self, f: F) -> CollaborateResult> + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { @@ -133,14 +137,14 @@ impl GridBlockMetaPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) + Ok(Some(GridBlockMetaDataChange { delta, md5: self.md5() })) } } } } } - fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut RowMeta) -> CollaborateResult>, { @@ -168,35 +172,35 @@ impl GridBlockMetaPad { } } -pub struct GridBlockMetaChange { +pub struct GridBlockMetaDataChange { pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta { - let json = serde_json::to_string(&block_meta).unwrap(); +pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta { + let json = serde_json::to_string(&grid_block_meta_data).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision { - let delta = make_block_meta_delta(block_meta); +pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision { + let delta = make_block_meta_delta(grid_block_meta_data); let bytes = delta.to_delta_bytes(); - let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); + let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes); revision.into() } -impl std::default::Default for GridBlockMetaPad { +impl std::default::Default for GridBlockMetaDataPad { fn default() -> Self { - let block_meta = GridBlockMeta { + let block_meta_data = GridBlockMetaData { block_id: uuid(), - rows: vec![], + row_metas: vec![], }; - let delta = make_block_meta_delta(&block_meta); - GridBlockMetaPad { - block_id: block_meta.block_id, - rows: block_meta.rows.into_iter().map(Arc::new).collect::>(), + let delta = make_block_meta_delta(&block_meta_data); + GridBlockMetaDataPad { + block_id: block_meta_data.block_id, + rows: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), delta, } } @@ -204,7 +208,7 @@ impl std::default::Default for GridBlockMetaPad { #[cfg(test)] mod tests { - use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; + use crate::client_grid::{GridBlockMetaDataPad, GridBlockMetaDelta}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; #[test] @@ -255,7 +259,7 @@ mod tests { assert_eq!(*pad.rows[2], row_2); } - fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { + fn test_row_meta(id: &str, pad: &GridBlockMetaDataPad) -> RowMeta { RowMeta { id: id.to_string(), block_id: pad.block_id.clone(), @@ -351,8 +355,8 @@ mod tests { ); } - fn test_pad() -> GridBlockMetaPad { + fn test_pad() -> GridBlockMetaDataPad { let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - GridBlockMetaPad::from_delta(delta).unwrap() + GridBlockMetaDataPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index a6be909ef6..3eb8af06c3 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -13,8 +13,8 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.build_context.grid_block.id); - self.build_context.grid_block_meta.rows.push(row); + let row = RowMeta::new(&self.build_context.grid_block.block_id); + self.build_context.grid_block_meta_data.row_metas.push(row); self.build_context.grid_block.row_count += 1; self } @@ -41,7 +41,7 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { mod tests { use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; - use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta}; #[test] fn create_default_grid_test() { @@ -63,7 +63,7 @@ mod tests { let grid_meta_delta = make_grid_delta(&grid_meta); let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); - let _: GridBlockMeta = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); + let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index a403b9c1c9..31c6ed0fbf 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -3,7 +3,7 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ - FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, + FieldChangeset, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -138,9 +138,9 @@ impl GridMetaPad { }) } - pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { + pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().any(|b| b.id == block.id) { + if grid.blocks.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { @@ -161,11 +161,11 @@ impl GridMetaPad { }) } - pub fn get_blocks(&self) -> Vec { + pub fn get_blocks(&self) -> Vec { self.grid_meta.blocks.clone() } - pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { + pub fn update_block(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; @@ -223,15 +223,17 @@ impl GridMetaPad { pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> where - F: FnOnce(&mut GridBlock) -> CollaborateResult>, + F: FnOnce(&mut GridBlockMeta) -> CollaborateResult>, { - self.modify_grid(|grid| match grid.blocks.iter().position(|block| block.id == block_id) { - None => { - tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); - Ok(None) - } - Some(index) => f(&mut grid.blocks[index]), - }) + self.modify_grid( + |grid| match grid.blocks.iter().position(|block| block.block_id == block_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); + Ok(None) + } + Some(index) => f(&mut grid.blocks[index]), + }, + ) } pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index 9dcb155557..f41d3601b4 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,7 +1,7 @@ -mod block_pad; +mod grid_block_meta_data_pad; mod grid_builder; mod grid_meta_pad; -pub use block_pad::*; +pub use grid_block_meta_data_pad::*; pub use grid_builder::*; pub use grid_meta_pad::*; diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 36e8e211e3..b3aa069170 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,6 +1,7 @@ -use crate::entities::{FieldMeta, FieldType, RowMeta}; +use crate::entities::{FieldMeta, FieldType, GridBlockMeta, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; +use std::hash::Hash; use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] @@ -12,7 +13,7 @@ pub struct Grid { pub field_orders: Vec, #[pb(index = 3)] - pub row_orders: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, ProtoBuf)] @@ -150,6 +151,12 @@ impl std::ops::DerefMut for RepeatedRowOrder { } } +impl std::convert::From> for RepeatedRowOrder { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] @@ -163,29 +170,35 @@ pub struct Row { } #[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedRow { +pub struct RepeatedGridBlock { #[pb(index = 1)] - pub items: Vec, + pub items: Vec, } -impl std::ops::Deref for RepeatedRow { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedRow { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedRow { - fn from(items: Vec) -> Self { +impl std::convert::From> for RepeatedGridBlock { + fn from(items: Vec) -> Self { Self { items } } } + +#[derive(Debug, Default, ProtoBuf)] +pub struct GridBlock { + #[pb(index = 1)] + pub block_id: String, + + #[pb(index = 2)] + pub rows: Vec, +} + +impl GridBlock { + pub fn new(block_id: &str, rows: Vec) -> Self { + Self { + block_id: block_id.to_owned(), + rows, + } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] @@ -247,6 +260,18 @@ impl AsRef for GridId { } } +#[derive(Clone, ProtoBuf, Default, Debug)] +pub struct GridBlockId { + #[pb(index = 1)] + pub value: String, +} + +impl AsRef for GridBlockId { + fn as_ref(&self) -> &str { + &self.value + } +} + #[derive(ProtoBuf, Default)] pub struct CreateRowPayload { #[pb(index = 1)] @@ -266,10 +291,10 @@ pub struct QueryFieldPayload { } #[derive(ProtoBuf, Default)] -pub struct QueryRowPayload { +pub struct QueryGridBlocksPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] - pub row_orders: RepeatedRowOrder, + pub blocks: Vec, } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 34d323c5df..62a545fcb0 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -16,13 +16,13 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlock { +pub struct GridBlockMeta { #[pb(index = 1)] - pub id: String, + pub block_id: String, #[pb(index = 2)] pub start_row_index: i32, @@ -31,7 +31,7 @@ pub struct GridBlock { pub row_count: i32, } -impl GridBlock { +impl GridBlockMeta { pub fn len(&self) -> i32 { self.start_row_index + self.row_count } @@ -41,22 +41,22 @@ impl GridBlock { } } -impl GridBlock { +impl GridBlockMeta { pub fn new() -> Self { - GridBlock { - id: uuid::Uuid::new_v4().to_string(), + GridBlockMeta { + block_id: uuid::Uuid::new_v4().to_string(), ..Default::default() } } } -pub struct GridBlockChangeset { +pub struct GridBlockMetaChangeset { pub block_id: String, pub start_row_index: Option, pub row_count: Option, } -impl GridBlockChangeset { +impl GridBlockMetaChangeset { pub fn from_row_count(block_id: &str, row_count: i32) -> Self { Self { block_id: block_id.to_string(), @@ -67,12 +67,12 @@ impl GridBlockChangeset { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlockMeta { +pub struct GridBlockMetaData { #[pb(index = 1)] pub block_id: String, #[pb(index = 2)] - pub rows: Vec, + pub row_metas: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] @@ -329,24 +329,24 @@ pub struct BuildGridContext { pub field_metas: Vec, #[pb(index = 2)] - pub grid_block: GridBlock, + pub grid_block: GridBlockMeta, #[pb(index = 3)] - pub grid_block_meta: GridBlockMeta, + pub grid_block_meta_data: GridBlockMetaData, } impl std::default::Default for BuildGridContext { fn default() -> Self { - let grid_block = GridBlock::new(); - let grid_block_meta = GridBlockMeta { - block_id: grid_block.id.clone(), - rows: vec![], + let grid_block = GridBlockMeta::new(); + let grid_block_meta_data = GridBlockMetaData { + block_id: grid_block.block_id.clone(), + row_metas: vec![], }; Self { field_metas: vec![], grid_block, - grid_block_meta, + grid_block_meta_data, } } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 9702766975..6e76d92a7c 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -28,7 +28,7 @@ pub struct Grid { // message fields pub id: ::std::string::String, pub field_orders: ::protobuf::RepeatedField, - pub row_orders: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl Grid { ::std::mem::replace(&mut self.field_orders, ::protobuf::RepeatedField::new()) } - // repeated .RowOrder row_orders = 3; + // repeated .GridBlockMeta blocks = 3; - pub fn get_row_orders(&self) -> &[RowOrder] { - &self.row_orders + pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { + &self.blocks } - pub fn clear_row_orders(&mut self) { - self.row_orders.clear(); + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { - self.row_orders = v; + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.row_orders + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for Grid { return false; } }; - for v in &self.row_orders { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for Grid { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_orders)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for Grid { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.row_orders { + for value in &self.blocks { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for Grid { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.row_orders { + for v in &self.blocks { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -240,10 +240,10 @@ impl ::protobuf::Message for Grid { |m: &Grid| { &m.field_orders }, |m: &mut Grid| { &mut m.field_orders }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "row_orders", - |m: &Grid| { &m.row_orders }, - |m: &mut Grid| { &mut m.row_orders }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "blocks", + |m: &Grid| { &m.blocks }, + |m: &mut Grid| { &mut m.blocks }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Grid", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for Grid { fn clear(&mut self) { self.id.clear(); self.field_orders.clear(); - self.row_orders.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } @@ -1749,29 +1749,29 @@ impl ::protobuf::reflect::ProtobufValue for Row { } #[derive(PartialEq,Clone,Default)] -pub struct RepeatedRow { +pub struct RepeatedGridBlock { // message fields - pub items: ::protobuf::RepeatedField, + pub items: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a RepeatedRow { - fn default() -> &'a RepeatedRow { - ::default_instance() +impl<'a> ::std::default::Default for &'a RepeatedGridBlock { + fn default() -> &'a RepeatedGridBlock { + ::default_instance() } } -impl RepeatedRow { - pub fn new() -> RepeatedRow { +impl RepeatedGridBlock { + pub fn new() -> RepeatedGridBlock { ::std::default::Default::default() } - // repeated .Row items = 1; + // repeated .GridBlock items = 1; - pub fn get_items(&self) -> &[Row] { + pub fn get_items(&self) -> &[GridBlock] { &self.items } pub fn clear_items(&mut self) { @@ -1779,22 +1779,22 @@ impl RepeatedRow { } // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { self.items = v; } // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.items } // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) } } -impl ::protobuf::Message for RepeatedRow { +impl ::protobuf::Message for RepeatedGridBlock { fn is_initialized(&self) -> bool { for v in &self.items { if !v.is_initialized() { @@ -1868,47 +1868,255 @@ impl ::protobuf::Message for RepeatedRow { Self::descriptor_static() } - fn new() -> RepeatedRow { - RepeatedRow::new() + fn new() -> RepeatedGridBlock { + RepeatedGridBlock::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "items", - |m: &RepeatedRow| { &m.items }, - |m: &mut RepeatedRow| { &mut m.items }, + |m: &RepeatedGridBlock| { &m.items }, + |m: &mut RepeatedGridBlock| { &mut m.items }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedRow", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedGridBlock", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static RepeatedRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedRow::new) + fn default_instance() -> &'static RepeatedGridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedGridBlock::new) } } -impl ::protobuf::Clear for RepeatedRow { +impl ::protobuf::Clear for RepeatedGridBlock { fn clear(&mut self) { self.items.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for RepeatedRow { +impl ::std::fmt::Debug for RepeatedGridBlock { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for RepeatedRow { +impl ::protobuf::reflect::ProtobufValue for RepeatedGridBlock { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct GridBlock { + // message fields + pub block_id: ::std::string::String, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlock { + fn default() -> &'a GridBlock { + ::default_instance() + } +} + +impl GridBlock { + pub fn new() -> GridBlock { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // repeated .Row rows = 2; + + + pub fn get_rows(&self) -> &[Row] { + &self.rows + } + pub fn clear_rows(&mut self) { + self.rows.clear(); + } + + // Param is passed by value, moved + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; + } + + // Mutable pointer to the field. + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows + } + + // Take field + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlock { + fn is_initialized(&self) -> bool { + for v in &self.rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + for value in &self.rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + for v in &self.rows { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlock { + GridBlock::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlock| { &m.block_id }, + |m: &mut GridBlock| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "rows", + |m: &GridBlock| { &m.rows }, + |m: &mut GridBlock| { &mut m.rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlock", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlock::new) + } +} + +impl ::protobuf::Clear for GridBlock { + fn clear(&mut self) { + self.block_id.clear(); + self.rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlock { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlock { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -2599,6 +2807,165 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockId { + // message fields + pub value: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockId { + fn default() -> &'a GridBlockId { + ::default_instance() + } +} + +impl GridBlockId { + pub fn new() -> GridBlockId { + ::std::default::Default::default() + } + + // string value = 1; + + + pub fn get_value(&self) -> &str { + &self.value + } + pub fn clear_value(&mut self) { + self.value.clear(); + } + + // Param is passed by value, moved + pub fn set_value(&mut self, v: ::std::string::String) { + self.value = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_value(&mut self) -> &mut ::std::string::String { + &mut self.value + } + + // Take field + pub fn take_value(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.value, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for GridBlockId { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.value)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.value.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.value); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.value.is_empty() { + os.write_string(1, &self.value)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlockId { + GridBlockId::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "value", + |m: &GridBlockId| { &m.value }, + |m: &mut GridBlockId| { &mut m.value }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockId", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockId::new) + } +} + +impl ::protobuf::Clear for GridBlockId { + fn clear(&mut self) { + self.value.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockId { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockId { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CreateRowPayload { // message fields @@ -3057,23 +3424,23 @@ impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload { } #[derive(PartialEq,Clone,Default)] -pub struct QueryRowPayload { +pub struct QueryGridBlocksPayload { // message fields pub grid_id: ::std::string::String, - pub row_orders: ::protobuf::SingularPtrField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a QueryRowPayload { - fn default() -> &'a QueryRowPayload { - ::default_instance() +impl<'a> ::std::default::Default for &'a QueryGridBlocksPayload { + fn default() -> &'a QueryGridBlocksPayload { + ::default_instance() } } -impl QueryRowPayload { - pub fn new() -> QueryRowPayload { +impl QueryGridBlocksPayload { + pub fn new() -> QueryGridBlocksPayload { ::std::default::Default::default() } @@ -3103,43 +3470,35 @@ impl QueryRowPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // .RepeatedRowOrder row_orders = 2; + // repeated .GridBlockMeta blocks = 2; - pub fn get_row_orders(&self) -> &RepeatedRowOrder { - self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { + &self.blocks } - pub fn clear_row_orders(&mut self) { - self.row_orders.clear(); - } - - pub fn has_row_orders(&self) -> bool { - self.row_orders.is_some() + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_row_orders(&mut self, v: RepeatedRowOrder) { - self.row_orders = ::protobuf::SingularPtrField::some(v); + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_orders(&mut self) -> &mut RepeatedRowOrder { - if self.row_orders.is_none() { - self.row_orders.set_default(); - } - self.row_orders.as_mut().unwrap() + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_row_orders(&mut self) -> RepeatedRowOrder { - self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } -impl ::protobuf::Message for QueryRowPayload { +impl ::protobuf::Message for QueryGridBlocksPayload { fn is_initialized(&self) -> bool { - for v in &self.row_orders { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -3155,7 +3514,7 @@ impl ::protobuf::Message for QueryRowPayload { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3172,10 +3531,10 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if let Some(ref v) = self.row_orders.as_ref() { - let len = v.compute_size(); + for value in &self.blocks { + let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } + }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -3185,11 +3544,11 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if let Some(ref v) = self.row_orders.as_ref() { + for v in &self.blocks { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; - } + }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -3220,8 +3579,8 @@ impl ::protobuf::Message for QueryRowPayload { Self::descriptor_static() } - fn new() -> QueryRowPayload { - QueryRowPayload::new() + fn new() -> QueryGridBlocksPayload { + QueryGridBlocksPayload::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -3230,59 +3589,59 @@ impl ::protobuf::Message for QueryRowPayload { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &QueryRowPayload| { &m.grid_id }, - |m: &mut QueryRowPayload| { &mut m.grid_id }, + |m: &QueryGridBlocksPayload| { &m.grid_id }, + |m: &mut QueryGridBlocksPayload| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "row_orders", - |m: &QueryRowPayload| { &m.row_orders }, - |m: &mut QueryRowPayload| { &mut m.row_orders }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "blocks", + |m: &QueryGridBlocksPayload| { &m.blocks }, + |m: &mut QueryGridBlocksPayload| { &mut m.blocks }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "QueryRowPayload", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryGridBlocksPayload", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static QueryRowPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(QueryRowPayload::new) + fn default_instance() -> &'static QueryGridBlocksPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryGridBlocksPayload::new) } } -impl ::protobuf::Clear for QueryRowPayload { +impl ::protobuf::Clear for QueryGridBlocksPayload { fn clear(&mut self) { self.grid_id.clear(); - self.row_orders.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for QueryRowPayload { +impl ::std::fmt::Debug for QueryGridBlocksPayload { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { +impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\x1a\nmeta.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ + \n\ngrid.proto\x1a\nmeta.proto\"n\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ - erR\x0bfieldOrders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\ - \trowOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ - id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\ - \x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.Fiel\ - dTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\ - \x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05wi\ - dth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_i\ - d\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ + erR\x0bfieldOrders\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockM\ + etaR\x06blocks\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ + FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ + n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ + idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ + id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"<\n\x08\ RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ @@ -3292,20 +3651,23 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\ \x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldId\ Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ - \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\ - \x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\";\n\x04Cell\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ - \x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\ - \x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\ - \x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\ - \x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\ - \x02\x20\x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11Qu\ - eryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\ - \n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfiel\ - dOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ - R\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrde\ - rR\trowOrdersb\x06proto3\ + \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"5\n\x11RepeatedGridBloc\ + k\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"@\n\tG\ + ridBlock\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x18\n\ + \x04rows\x18\x02\x20\x03(\x0b2\x04.RowR\x04rows\";\n\x04Cell\x12\x19\n\ + \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ + \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ + \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ + \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ + e\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ + \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ + _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\x02\x20\ + \x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryField\ + Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ + ld_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\ + Y\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12&\n\x06blocks\x18\x02\x20\x03(\x0b2\x0e.GridBlockMetaR\x06\ + blocksb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index d56f2ee5a3..0dcde28a6b 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,10 +96,10 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .GridBlock blocks = 3; + // repeated .GridBlockMeta blocks = 3; - pub fn get_blocks(&self) -> &[GridBlock] { + pub fn get_blocks(&self) -> &[GridBlockMeta] { &self.blocks } pub fn clear_blocks(&mut self) { @@ -107,17 +107,17 @@ impl GridMeta { } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { self.blocks = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.blocks } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -240,7 +240,7 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "blocks", |m: &GridMeta| { &m.blocks }, |m: &mut GridMeta| { &mut m.blocks }, @@ -280,240 +280,12 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta { } } -#[derive(PartialEq,Clone,Default)] -pub struct GridBlock { - // message fields - pub id: ::std::string::String, - pub start_row_index: i32, - pub row_count: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GridBlock { - fn default() -> &'a GridBlock { - ::default_instance() - } -} - -impl GridBlock { - pub fn new() -> GridBlock { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // int32 start_row_index = 2; - - - pub fn get_start_row_index(&self) -> i32 { - self.start_row_index - } - pub fn clear_start_row_index(&mut self) { - self.start_row_index = 0; - } - - // Param is passed by value, moved - pub fn set_start_row_index(&mut self, v: i32) { - self.start_row_index = v; - } - - // int32 row_count = 3; - - - pub fn get_row_count(&self) -> i32 { - self.row_count - } - pub fn clear_row_count(&mut self) { - self.row_count = 0; - } - - // Param is passed by value, moved - pub fn set_row_count(&mut self, v: i32) { - self.row_count = v; - } -} - -impl ::protobuf::Message for GridBlock { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.start_row_index = tmp; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.row_count = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if self.start_row_index != 0 { - my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); - } - if self.row_count != 0 { - my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if self.start_row_index != 0 { - os.write_int32(2, self.start_row_index)?; - } - if self.row_count != 0 { - os.write_int32(3, self.row_count)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GridBlock { - GridBlock::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &GridBlock| { &m.id }, - |m: &mut GridBlock| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "start_row_index", - |m: &GridBlock| { &m.start_row_index }, - |m: &mut GridBlock| { &mut m.start_row_index }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "row_count", - |m: &GridBlock| { &m.row_count }, - |m: &mut GridBlock| { &mut m.row_count }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlock", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GridBlock { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlock::new) - } -} - -impl ::protobuf::Clear for GridBlock { - fn clear(&mut self) { - self.id.clear(); - self.start_row_index = 0; - self.row_count = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GridBlock { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GridBlock { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct GridBlockMeta { // message fields pub block_id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, + pub start_row_index: i32, + pub row_count: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -556,39 +328,39 @@ impl GridBlockMeta { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .RowMeta rows = 2; + // int32 start_row_index = 2; - pub fn get_rows(&self) -> &[RowMeta] { - &self.rows + pub fn get_start_row_index(&self) -> i32 { + self.start_row_index } - pub fn clear_rows(&mut self) { - self.rows.clear(); + pub fn clear_start_row_index(&mut self) { + self.start_row_index = 0; } // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; + pub fn set_start_row_index(&mut self, v: i32) { + self.start_row_index = v; } - // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows + // int32 row_count = 3; + + + pub fn get_row_count(&self) -> i32 { + self.row_count + } + pub fn clear_row_count(&mut self) { + self.row_count = 0; } - // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + // Param is passed by value, moved + pub fn set_row_count(&mut self, v: i32) { + self.row_count = v; } } impl ::protobuf::Message for GridBlockMeta { fn is_initialized(&self) -> bool { - for v in &self.rows { - if !v.is_initialized() { - return false; - } - }; true } @@ -600,7 +372,18 @@ impl ::protobuf::Message for GridBlockMeta { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.start_row_index = tmp; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.row_count = tmp; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -617,10 +400,12 @@ impl ::protobuf::Message for GridBlockMeta { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.rows { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; + if self.start_row_index != 0 { + my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); + } + if self.row_count != 0 { + my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -630,11 +415,12 @@ impl ::protobuf::Message for GridBlockMeta { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.rows { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; + if self.start_row_index != 0 { + os.write_int32(2, self.start_row_index)?; + } + if self.row_count != 0 { + os.write_int32(3, self.row_count)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -678,10 +464,15 @@ impl ::protobuf::Message for GridBlockMeta { |m: &GridBlockMeta| { &m.block_id }, |m: &mut GridBlockMeta| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridBlockMeta| { &m.rows }, - |m: &mut GridBlockMeta| { &mut m.rows }, + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "start_row_index", + |m: &GridBlockMeta| { &m.start_row_index }, + |m: &mut GridBlockMeta| { &mut m.start_row_index }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "row_count", + |m: &GridBlockMeta| { &m.row_count }, + |m: &mut GridBlockMeta| { &mut m.row_count }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlockMeta", @@ -700,7 +491,8 @@ impl ::protobuf::Message for GridBlockMeta { impl ::protobuf::Clear for GridBlockMeta { fn clear(&mut self) { self.block_id.clear(); - self.rows.clear(); + self.start_row_index = 0; + self.row_count = 0; self.unknown_fields.clear(); } } @@ -717,6 +509,214 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockMetaData { + // message fields + pub block_id: ::std::string::String, + pub row_metas: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockMetaData { + fn default() -> &'a GridBlockMetaData { + ::default_instance() + } +} + +impl GridBlockMetaData { + pub fn new() -> GridBlockMetaData { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // repeated .RowMeta row_metas = 2; + + + pub fn get_row_metas(&self) -> &[RowMeta] { + &self.row_metas + } + pub fn clear_row_metas(&mut self) { + self.row_metas.clear(); + } + + // Param is passed by value, moved + pub fn set_row_metas(&mut self, v: ::protobuf::RepeatedField) { + self.row_metas = v; + } + + // Mutable pointer to the field. + pub fn mut_row_metas(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_metas + } + + // Take field + pub fn take_row_metas(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_metas, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlockMetaData { + fn is_initialized(&self) -> bool { + for v in &self.row_metas { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_metas)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + for value in &self.row_metas { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + for v in &self.row_metas { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlockMetaData { + GridBlockMetaData::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlockMetaData| { &m.block_id }, + |m: &mut GridBlockMetaData| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_metas", + |m: &GridBlockMetaData| { &m.row_metas }, + |m: &mut GridBlockMetaData| { &mut m.row_metas }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMetaData", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockMetaData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMetaData::new) + } +} + +impl ::protobuf::Clear for GridBlockMetaData { + fn clear(&mut self) { + self.block_id.clear(); + self.row_metas.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockMetaData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct FieldMeta { // message fields @@ -3119,8 +3119,8 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { pub struct BuildGridContext { // message fields pub field_metas: ::protobuf::RepeatedField, - pub grid_block: ::protobuf::SingularPtrField, - pub grid_block_meta: ::protobuf::SingularPtrField, + pub grid_block: ::protobuf::SingularPtrField, + pub grid_block_meta_data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3162,11 +3162,11 @@ impl BuildGridContext { ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) } - // .GridBlock grid_block = 2; + // .GridBlockMeta grid_block = 2; - pub fn get_grid_block(&self) -> &GridBlock { - self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_grid_block(&self) -> &GridBlockMeta { + self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) } pub fn clear_grid_block(&mut self) { self.grid_block.clear(); @@ -3177,13 +3177,13 @@ impl BuildGridContext { } // Param is passed by value, moved - pub fn set_grid_block(&mut self, v: GridBlock) { + pub fn set_grid_block(&mut self, v: GridBlockMeta) { self.grid_block = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block(&mut self) -> &mut GridBlock { + pub fn mut_grid_block(&mut self) -> &mut GridBlockMeta { if self.grid_block.is_none() { self.grid_block.set_default(); } @@ -3191,41 +3191,41 @@ impl BuildGridContext { } // Take field - pub fn take_grid_block(&mut self) -> GridBlock { - self.grid_block.take().unwrap_or_else(|| GridBlock::new()) + pub fn take_grid_block(&mut self) -> GridBlockMeta { + self.grid_block.take().unwrap_or_else(|| GridBlockMeta::new()) } - // .GridBlockMeta grid_block_meta = 3; + // .GridBlockMetaData grid_block_meta_data = 3; - pub fn get_grid_block_meta(&self) -> &GridBlockMeta { - self.grid_block_meta.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_grid_block_meta_data(&self) -> &GridBlockMetaData { + self.grid_block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_grid_block_meta(&mut self) { - self.grid_block_meta.clear(); + pub fn clear_grid_block_meta_data(&mut self) { + self.grid_block_meta_data.clear(); } - pub fn has_grid_block_meta(&self) -> bool { - self.grid_block_meta.is_some() + pub fn has_grid_block_meta_data(&self) -> bool { + self.grid_block_meta_data.is_some() } // Param is passed by value, moved - pub fn set_grid_block_meta(&mut self, v: GridBlockMeta) { - self.grid_block_meta = ::protobuf::SingularPtrField::some(v); + pub fn set_grid_block_meta_data(&mut self, v: GridBlockMetaData) { + self.grid_block_meta_data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block_meta(&mut self) -> &mut GridBlockMeta { - if self.grid_block_meta.is_none() { - self.grid_block_meta.set_default(); + pub fn mut_grid_block_meta_data(&mut self) -> &mut GridBlockMetaData { + if self.grid_block_meta_data.is_none() { + self.grid_block_meta_data.set_default(); } - self.grid_block_meta.as_mut().unwrap() + self.grid_block_meta_data.as_mut().unwrap() } // Take field - pub fn take_grid_block_meta(&mut self) -> GridBlockMeta { - self.grid_block_meta.take().unwrap_or_else(|| GridBlockMeta::new()) + pub fn take_grid_block_meta_data(&mut self) -> GridBlockMetaData { + self.grid_block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new()) } } @@ -3241,7 +3241,7 @@ impl ::protobuf::Message for BuildGridContext { return false; } }; - for v in &self.grid_block_meta { + for v in &self.grid_block_meta_data { if !v.is_initialized() { return false; } @@ -3260,7 +3260,7 @@ impl ::protobuf::Message for BuildGridContext { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?; }, 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta_data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3282,7 +3282,7 @@ impl ::protobuf::Message for BuildGridContext { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if let Some(ref v) = self.grid_block_meta.as_ref() { + if let Some(ref v) = self.grid_block_meta_data.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -3302,7 +3302,7 @@ impl ::protobuf::Message for BuildGridContext { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - if let Some(ref v) = self.grid_block_meta.as_ref() { + if let Some(ref v) = self.grid_block_meta_data.as_ref() { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -3350,15 +3350,15 @@ impl ::protobuf::Message for BuildGridContext { |m: &BuildGridContext| { &m.field_metas }, |m: &mut BuildGridContext| { &mut m.field_metas }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "grid_block", |m: &BuildGridContext| { &m.grid_block }, |m: &mut BuildGridContext| { &mut m.grid_block }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "grid_block_meta", - |m: &BuildGridContext| { &m.grid_block_meta }, - |m: &mut BuildGridContext| { &mut m.grid_block_meta }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_block_meta_data", + |m: &BuildGridContext| { &m.grid_block_meta_data }, + |m: &mut BuildGridContext| { &mut m.grid_block_meta_data }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "BuildGridContext", @@ -3378,7 +3378,7 @@ impl ::protobuf::Clear for BuildGridContext { fn clear(&mut self) { self.field_metas.clear(); self.grid_block.clear(); - self.grid_block_meta.clear(); + self.grid_block_meta_data.clear(); self.unknown_fields.clear(); } } @@ -3458,56 +3458,57 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"k\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ - s\x12\"\n\x06blocks\x18\x03\x20\x03(\x0b2\n.GridBlockR\x06blocks\"`\n\tG\ - ridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_i\ - ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ - \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ - \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ - RowMetaR\x04rows\"\xdf\x01\n\tFieldMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04des\ - c\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ - .FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froz\ - en\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05\ - width\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ - \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\ - _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\ - \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\ - ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\ - \x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\ - \x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x07\x20\ - \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\ - \x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of\ - _field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0c\ - one_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyData\x12\x17\n\x07\ - type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01\ - (\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\ - \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntr\ - yR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\ - \x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12CellB\ - yFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05v\ - alue\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\n\ - \x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ - ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ - \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ - dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ - \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ - \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\x08Cell\ - Meta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04d\ - ata\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ - \x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07field\ - Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\ - \"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\ - \x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\x02\x20\x01(\x0b2\ - \n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\x03\x20\x01(\x0b2\ - \x0e.GridBlockMetaR\rgridBlockMeta*d\n\tFieldType\x12\x0c\n\x08RichText\ - \x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\ - \x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08C\ - heckbox\x10\x05b\x06proto3\ + s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\ + \n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ + \x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\ + \n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMetaDat\ + a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_metas\ + \x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldMeta\ + \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\ + \x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nf\ + ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06fro\ + zen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\ + \x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\ + \x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\n\ + \x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\ + \x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ + \x03\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ + .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\ + \x03R\x06frozen\x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibi\ + lity\x12\x16\n\x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12#\n\x0cty\ + pe_options\x18\x08\x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\ + \r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\ + \x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type\ + _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ + eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ + Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ + \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ + \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ + \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ + \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ + \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ + \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ + \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ + \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ + ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ + llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ + \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ + \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ + _of_visibility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\t\ + R\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\ + \x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ + \x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\ + \x04dataB\r\n\x0bone_of_data\"\xb3\x01\n\x10BuildGridContext\x12+\n\x0bf\ + ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ngrid_b\ + lock\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tgridBlock\x12C\n\x14grid_\ + block_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\x11gridBloc\ + kMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ + \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ + \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ + o3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index ed6fc83b65..31119b015d 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -4,7 +4,7 @@ import "meta.proto"; message Grid { string id = 1; repeated FieldOrder field_orders = 2; - repeated RowOrder row_orders = 3; + repeated GridBlockMeta blocks = 3; } message Field { string id = 1; @@ -36,8 +36,12 @@ message Row { map cell_by_field_id = 2; int32 height = 3; } -message RepeatedRow { - repeated Row items = 1; +message RepeatedGridBlock { + repeated GridBlock items = 1; +} +message GridBlock { + string block_id = 1; + repeated Row rows = 2; } message Cell { string field_id = 1; @@ -52,6 +56,9 @@ message CreateGridPayload { message GridId { string value = 1; } +message GridBlockId { + string value = 1; +} message CreateRowPayload { string grid_id = 1; oneof one_of_upper_row_id { string upper_row_id = 2; }; @@ -60,7 +67,7 @@ message QueryFieldPayload { string grid_id = 1; RepeatedFieldOrder field_orders = 2; } -message QueryRowPayload { +message QueryGridBlocksPayload { string grid_id = 1; - RepeatedRowOrder row_orders = 2; + repeated GridBlockMeta blocks = 2; } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index b1c8b77c40..aa23f08a02 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,16 +3,16 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated FieldMeta fields = 2; - repeated GridBlock blocks = 3; -} -message GridBlock { - string id = 1; - int32 start_row_index = 2; - int32 row_count = 3; + repeated GridBlockMeta blocks = 3; } message GridBlockMeta { string block_id = 1; - repeated RowMeta rows = 2; + int32 start_row_index = 2; + int32 row_count = 3; +} +message GridBlockMetaData { + string block_id = 1; + repeated RowMeta row_metas = 2; } message FieldMeta { string id = 1; @@ -63,8 +63,8 @@ message CellMetaChangeset { } message BuildGridContext { repeated FieldMeta field_metas = 1; - GridBlock grid_block = 2; - GridBlockMeta grid_block_meta = 3; + GridBlockMeta grid_block = 2; + GridBlockMetaData grid_block_meta_data = 3; } enum FieldType { RichText = 0; From 9a40fc997450414cc1481b4ede0ee2859347345f Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 17 Mar 2022 20:59:21 +0800 Subject: [PATCH 047/179] chore: lazy load row data --- .../workspace/application/grid/grid_bloc.dart | 90 ++++++++----------- .../flowy-grid/src/dart_notification.rs | 1 + .../src/entities/grid.rs | 2 +- 3 files changed, 40 insertions(+), 53 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 8fea0b04df..b5e6cc67d5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -17,8 +17,6 @@ class GridBloc extends Bloc { final View view; final GridService service; final GridListener listener; - Grid? _grid; - List? _fields; GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) { on( @@ -27,8 +25,6 @@ class GridBloc extends Bloc { initial: (InitialGrid value) async { await _startGridListening(); await _loadGrid(emit); - await _loadFields(emit); - await _loadGridInfo(emit); }, createRow: (_CreateRow value) { service.createRow(gridId: view.id); @@ -48,17 +44,13 @@ class GridBloc extends Bloc { } Future _startGridListening() async { - listener.createRowNotifier.addPublishListener((result) { - result.fold((repeatedRow) { + listener.blockUpdateNotifier.addPublishListener((result) { + result.fold((blockId) { // - Log.info("$repeatedRow"); + Log.info("$blockId"); }, (err) => null); }); - listener.deleteRowNotifier.addPublishListener((result) { - result.fold((l) => null, (r) => null); - }); - listener.start(); } @@ -66,52 +58,42 @@ class GridBloc extends Bloc { final result = await service.openGrid(gridId: view.id); result.fold( (grid) { - _grid = grid; - }, - (err) { - emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); + _loadFields(grid, emit); + emit(state.copyWith(grid: Some(grid))); }, + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), ); } - Future _loadFields(Emitter emit) async { - if (_grid != null) { - final result = await service.getFields(gridId: _grid!.id, fieldOrders: _grid!.fieldOrders); - result.fold( - (fields) { - _fields = fields.items; - }, - (err) { - emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); - }, - ); - } + Future _loadFields(Grid grid, Emitter emit) async { + final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); + result.fold( + (fields) { + _loadGridBlocks(grid, emit); + emit(state.copyWith(fields: fields.items)); + }, + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + ); } - Future _loadGridInfo(Emitter emit) async { - final grid = _grid; - if (grid != null && _fields != null) { - final result = await service.getGridBlocks( - gridId: grid.id, - blocks: grid.blocks, - ); + Future _loadGridBlocks(Grid grid, Emitter emit) async { + final result = await service.getGridBlocks(gridId: grid.id, blocks: grid.blocks); - result.fold((repeatedGridBlock) { - final blocks = repeatedGridBlock.items; - final gridInfo = GridInfo( - gridId: grid.id, - blocks: blocks, - fields: _fields!, - ); - emit( - state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), - ); - }, (err) { - emit( - state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()), - ); - }); - } + result.fold((repeatedGridBlock) { + final blocks = repeatedGridBlock.items; + final gridInfo = GridInfo( + gridId: grid.id, + blocks: blocks, + fields: _fields!, + ); + emit( + state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), + ); + }, (err) { + emit( + state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()), + ); + }); } } @@ -128,12 +110,16 @@ abstract class GridEvent with _$GridEvent { abstract class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, - required Option> gridInfo, + required List fields, + required List rows, + required Option grid, }) = _GridState; factory GridState.initial() => GridState( loadingState: const _Loading(), - gridInfo: none(), + fields: [], + rows: [], + grid: none(), ); } diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index ba0396bf7f..82ab35bdee 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -6,6 +6,7 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; pub enum GridNotification { Unknown = 0, GridDidUpdateBlock = 10, + GridDidCreateBlock = 11, GridDidUpdateCells = 20, GridDidUpdateFields = 30, diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index b3aa069170..95a0454eb1 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -187,7 +187,7 @@ pub struct GridBlock { pub block_id: String, #[pb(index = 2)] - pub rows: Vec, + pub rows: Vec, } impl GridBlock { From 05bcd38534b6479e9990fb786a44b4d717976c27 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 18 Mar 2022 17:14:46 +0800 Subject: [PATCH 048/179] chore: render rows --- .../lib/startup/home_deps_resolver.dart | 18 +- .../grid/cell_bloc/cell_service.dart | 13 +- .../lib/workspace/application/grid/data.dart | 43 - .../workspace/application/grid/grid_bloc.dart | 100 ++- ..._listener.dart => grid_block_service.dart} | 54 +- .../application/grid/grid_listenr.dart | 4 + .../application/grid/grid_service.dart | 24 +- .../workspace/application/grid/row_bloc.dart | 39 +- .../application/grid/row_service.dart | 28 +- .../plugins/grid/src/grid_page.dart | 34 +- .../src/widgets/content/cell_builder.dart | 17 +- .../src/widgets/content/checkbox_cell.dart | 8 +- .../grid/src/widgets/content/date_cell.dart | 8 +- .../grid/src/widgets/content/grid_row.dart | 29 +- .../grid/src/widgets/content/number_cell.dart | 8 +- .../src/widgets/content/selection_cell.dart | 4 +- .../grid/src/widgets/content/text_cell.dart | 8 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../flowy-error-code/code.pbenum.dart | 8 +- .../flowy-error-code/code.pbjson.dart | 7 +- .../flowy-grid-data-model/grid.pb.dart | 225 ++++- .../flowy-grid-data-model/grid.pbjson.dart | 50 +- .../flowy-grid-data-model/meta.pb.dart | 72 +- .../flowy-grid-data-model/meta.pbjson.dart | 20 +- .../flowy-grid/dart_notification.pbenum.dart | 2 + .../flowy-grid/dart_notification.pbjson.dart | 3 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 8 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 9 +- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 41 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 10 +- frontend/rust-lib/flowy-grid/src/manager.rs | 6 +- .../src/protobuf/model/dart_notification.rs | 10 +- .../src/protobuf/model/event_map.rs | 22 +- .../protobuf/proto/dart_notification.proto | 1 + .../src/protobuf/proto/event_map.proto | 7 +- .../src/services/block_meta_editor.rs | 70 +- .../flowy-grid/src/services/grid_editor.rs | 111 ++- .../flowy-grid/src/services/row/row_loader.rs | 40 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 40 +- shared-lib/Cargo.lock | 1 + ...eta_data_pad.rs => grid_block_meta_pad.rs} | 98 +- .../src/client_grid/grid_builder.rs | 14 +- .../src/client_grid/grid_meta_pad.rs | 16 +- .../src/client_grid/mod.rs | 4 +- shared-lib/flowy-error-code/src/code.rs | 8 +- .../src/protobuf/model/code.rs | 20 +- .../src/protobuf/proto/code.proto | 5 +- shared-lib/flowy-grid-data-model/Cargo.toml | 1 + .../src/entities/grid.rs | 48 +- .../src/entities/meta.rs | 17 +- shared-lib/flowy-grid-data-model/src/lib.rs | 1 + .../flowy-grid-data-model/src/parser/grid.rs | 82 ++ .../flowy-grid-data-model/src/parser/id.rs | 20 + .../flowy-grid-data-model/src/parser/mod.rs | 5 + .../src/protobuf/model/grid.rs | 843 +++++++++++++++--- .../src/protobuf/model/meta.rs | 225 +++-- .../src/protobuf/proto/grid.proto | 19 +- .../src/protobuf/proto/meta.proto | 8 +- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- 61 files changed, 1884 insertions(+), 778 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/{grid_listener.dart => grid_block_service.dart} (55%) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart rename shared-lib/flowy-collaboration/src/client_grid/{grid_block_meta_data_pad.rs => grid_block_meta_pad.rs} (79%) create mode 100644 shared-lib/flowy-grid-data-model/src/parser/grid.rs create mode 100644 shared-lib/flowy-grid-data-model/src/parser/id.rs create mode 100644 shared-lib/flowy-grid-data-model/src/parser/mod.rs diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 084612ca61..2dcf6ca077 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -17,8 +17,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; -import '../workspace/application/grid/grid_listener.dart'; - class HomeDepsResolver { static Future resolve(GetIt getIt) async { getIt.registerFactoryParam( @@ -93,13 +91,13 @@ class HomeDepsResolver { // Grid getIt.registerFactoryParam( - (view, _) => GridBloc(view: view, service: GridService(), listener: GridListener(gridId: view.id)), + (view, _) => GridBloc(view: view, service: GridService()), ); getIt.registerFactoryParam( (data, _) => RowBloc( - service: RowService(data), - listener: RowListener(rowId: data.row.id), + rowService: RowService(data), + listener: RowListener(rowId: data.rowId), ), ); @@ -110,31 +108,31 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => TextCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => SelectionCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => NumberCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => DateCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => CheckboxCellBloc( service: CellService(context), ), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index 456615220d..44cf86e5d2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,11 +1,11 @@ +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class CellService { - final CellContext context; + final GridCellData context; CellService(this.context); @@ -18,12 +18,3 @@ class CellService { return GridEventUpdateCell(payload).send(); } } - -class CellContext { - final String gridId; - final String rowId; - final Field field; - final Cell? cell; - - CellContext({required this.rowId, required this.gridId, required this.field, required this.cell}); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 05ca053b8c..ff1b1e3efc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,47 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:equatable/equatable.dart'; - -class GridInfo { - final String gridId; - List gridBlocks; - List fields; - - GridInfo({ - required this.gridId, - required this.gridBlocks, - required this.fields, - }); - - GridRowData rowAtIndex(int index) { - final row = rows[index]; - return GridRowData( - gridId: gridId, - row: row, - fields: fields, - cellMap: row.cellByFieldId, - ); - } - - int numberOfRows() { - return rows.length; - } -} - -class GridRowData extends Equatable { - final String gridId; - final Row row; - final List fields; - final Map cellMap; - const GridRowData({ - required this.gridId, - required this.row, - required this.fields, - required this.cellMap, - }); - - @override - List get props => [row.hashCode, cellMap]; -} class GridColumnData { final List fields; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index b5e6cc67d5..1db06d815c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,14 +1,12 @@ import 'dart:async'; - import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'data.dart'; -import 'grid_listener.dart'; +import 'grid_block_service.dart'; +import 'grid_listenr.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -16,14 +14,16 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final View view; final GridService service; - final GridListener listener; + late GridListener _gridListener; + late GridBlockService _blockService; + + GridBloc({required this.view, required this.service}) : super(GridState.initial()) { + _gridListener = GridListener(); - GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) { on( (event, emit) async { await event.map( initial: (InitialGrid value) async { - await _startGridListening(); await _loadGrid(emit); }, createRow: (_CreateRow value) { @@ -32,6 +32,9 @@ class GridBloc extends Bloc { delete: (_Delete value) {}, rename: (_Rename value) {}, updateDesc: (_Desc value) {}, + didLoadRows: (_DidLoadRows value) { + emit(state.copyWith(rows: value.rows)); + }, ); }, ); @@ -39,61 +42,63 @@ class GridBloc extends Bloc { @override Future close() async { - await listener.close(); + await _gridListener.stop(); + await _blockService.stop(); return super.close(); } Future _startGridListening() async { - listener.blockUpdateNotifier.addPublishListener((result) { - result.fold((blockId) { - // - Log.info("$blockId"); - }, (err) => null); - }); + _blockService.didLoadRowscallback = (rows) { + add(GridEvent.didLoadRows(rows)); + }; - listener.start(); + _gridListener.start(); } Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); - result.fold( - (grid) { - _loadFields(grid, emit); - emit(state.copyWith(grid: Some(grid))); - }, - (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + + return Future( + () => result.fold( + (grid) async => await _loadFields(grid, emit), + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + ), ); } Future _loadFields(Grid grid, Emitter emit) async { final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); - result.fold( - (fields) { - _loadGridBlocks(grid, emit); - emit(state.copyWith(fields: fields.items)); - }, - (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + return Future( + () => result.fold( + (fields) => _loadGridBlocks(grid, fields.items, emit), + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + ), ); } - Future _loadGridBlocks(Grid grid, Emitter emit) async { - final result = await service.getGridBlocks(gridId: grid.id, blocks: grid.blocks); + Future _loadGridBlocks(Grid grid, List fields, Emitter emit) async { + final result = await service.getGridBlocks(gridId: grid.id, blockOrders: grid.blockOrders); + result.fold( + (repeatedGridBlock) { + final gridBlocks = repeatedGridBlock.items; + final gridId = view.id; + _blockService = GridBlockService( + gridId: gridId, + fields: fields, + gridBlocks: gridBlocks, + ); + final rows = _blockService.rows(); - result.fold((repeatedGridBlock) { - final blocks = repeatedGridBlock.items; - final gridInfo = GridInfo( - gridId: grid.id, - blocks: blocks, - fields: _fields!, - ); - emit( - state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), - ); - }, (err) { - emit( - state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()), - ); - }); + _startGridListening(); + emit(state.copyWith( + grid: Some(grid), + fields: Some(fields), + rows: rows, + loadingState: GridLoadingState.finish(left(unit)), + )); + }, + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)), rows: [])), + ); } } @@ -104,20 +109,21 @@ abstract class GridEvent with _$GridEvent { const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; + const factory GridEvent.didLoadRows(List rows) = _DidLoadRows; } @freezed abstract class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, - required List fields, - required List rows, + required Option> fields, + required List rows, required Option grid, }) = _GridState; factory GridState.initial() => GridState( loadingState: const _Loading(), - fields: [], + fields: none(), rows: [], grid: none(), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart similarity index 55% rename from frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart rename to frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 67f69b57b6..973f412e9e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -1,23 +1,67 @@ +import 'dart:collection'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -import 'package:dartz/dartz.dart'; +import 'grid_service.dart'; + +typedef DidLoadRowsCallback = void Function(List); typedef GridBlockUpdateNotifiedValue = Either; -class GridListener { +class GridBlockService { + String gridId; + List fields; + LinkedHashMap blockMap = LinkedHashMap(); + late GridBlockListener _blockListener; + DidLoadRowsCallback? didLoadRowscallback; + + GridBlockService({required this.gridId, required this.fields, required List gridBlocks}) { + for (final gridBlock in gridBlocks) { + blockMap[gridBlock.blockId] = gridBlock; + } + + _blockListener = GridBlockListener(gridId: gridId); + _blockListener.blockUpdateNotifier.addPublishListener((result) { + result.fold((blockId) { + // + }, (err) => null); + }); + } + + List rows() { + List rows = []; + blockMap.forEach((_, gridBlock) { + rows.addAll(gridBlock.rowIds.map( + (rowId) => GridRowData( + gridId: gridId, + fields: fields, + blockId: gridBlock.blockId, + rowId: rowId, + ), + )); + }); + return rows; + } + + Future stop() async { + await _blockListener.stop(); + } +} + +class GridBlockListener { final String gridId; PublishNotifier blockUpdateNotifier = PublishNotifier(); StreamSubscription? _subscription; late GridNotificationParser _parser; - GridListener({required this.gridId}); + GridBlockListener({required this.gridId}); void start() { _parser = GridNotificationParser( @@ -44,7 +88,7 @@ class GridListener { } } - Future close() async { + Future stop() async { await _subscription?.cancel(); blockUpdateNotifier.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart new file mode 100644 index 0000000000..55e29d915c --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart @@ -0,0 +1,4 @@ +class GridListener { + void start() {} + Future stop() async {} +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 62208c8d05..976860029e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,7 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:equatable/equatable.dart'; class GridService { Future> openGrid({required String gridId}) async { @@ -15,15 +15,15 @@ class GridService { Future> createRow({required String gridId, Option? upperRowId}) { CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; - upperRowId?.fold(() => null, (id) => payload.upperRowId = id); + upperRowId?.fold(() => null, (id) => payload.startRowId = id); return GridEventCreateRow(payload).send(); } Future> getGridBlocks( - {required String gridId, required List blocks}) { + {required String gridId, required List blockOrders}) { final payload = QueryGridBlocksPayload.create() ..gridId = gridId - ..blocks.addAll(blocks); + ..blockOrders.addAll(blockOrders); return GridEventGetGridBlocks(payload).send(); } @@ -34,3 +34,19 @@ class GridService { return GridEventGetFields(payload).send(); } } + +class GridRowData extends Equatable { + final String gridId; + final String rowId; + final String blockId; + final List fields; + const GridRowData({ + required this.gridId, + required this.rowId, + required this.blockId, + required this.fields, + }); + + @override + List get props => [rowId]; +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 16195af592..32525a1bb7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -2,25 +2,26 @@ import 'package:flowy_sdk/log.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'data.dart'; +import 'grid_service.dart'; import 'row_listener.dart'; import 'row_service.dart'; part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { - final RowService service; + final RowService rowService; final RowListener listener; - RowBloc({required this.service, required this.listener}) : super(RowState.initial(service.rowData)) { + RowBloc({required this.rowService, required this.listener}) : super(RowState.initial(rowService.rowData)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async { _startRowListening(); + await _loadCellDatas(emit); }, createRow: (_CreateRow value) { - service.createRow(); + rowService.createRow(); }, activeRow: (_ActiveRow value) { emit(state.copyWith(active: true)); @@ -55,6 +56,25 @@ class RowBloc extends Bloc { listener.start(); } + + Future _loadCellDatas(Emitter emit) async { + final result = await rowService.getRow(); + result.fold( + (row) { + final cellDatas = rowService.rowData.fields.map((field) { + final cell = row.cellByFieldId[field.id]; + return GridCellData( + rowId: row.id, + gridId: rowService.rowData.gridId, + cell: cell, + field: field, + ); + }).toList(); + emit(state.copyWith(cellDatas: cellDatas, rowHeight: row.height.toDouble())); + }, + (e) => Log.error(e), + ); + } } @freezed @@ -68,9 +88,16 @@ abstract class RowEvent with _$RowEvent { @freezed abstract class RowState with _$RowState { const factory RowState({ - required GridRowData data, + required String rowId, + required double rowHeight, + required List cellDatas, required bool active, }) = _RowState; - factory RowState.initial(GridRowData data) => RowState(data: data, active: false); + factory RowState.initial(GridRowData data) => RowState( + rowId: data.rowId, + active: false, + rowHeight: 0, + cellDatas: [], + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart index 03d732f862..986442c47e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -1,9 +1,10 @@ -import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'grid_service.dart'; + class RowService { final GridRowData rowData; @@ -12,8 +13,31 @@ class RowService { Future> createRow() { CreateRowPayload payload = CreateRowPayload.create() ..gridId = rowData.gridId - ..upperRowId = rowData.row.id; + ..startRowId = rowData.rowId; return GridEventCreateRow(payload).send(); } + + Future> getRow() { + QueryRowPayload payload = QueryRowPayload.create() + ..gridId = rowData.gridId + ..blockId = rowData.blockId + ..rowId = rowData.rowId; + + return GridEventGetRow(payload).send(); + } +} + +class GridCellData { + final String gridId; + final String rowId; + final Field field; + final Cell? cell; + + GridCellData({ + required this.rowId, + required this.gridId, + required this.field, + required this.cell, + }); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index c396e7d71f..4e7747ac1d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,5 +1,4 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; @@ -41,7 +40,7 @@ class _GridPageState extends State { return state.loadingState.map( loading: (_) => const Center(child: CircularProgressIndicator.adaptive()), finish: (result) => result.successOrFail.fold( - (_) => const GridBody(), + (_) => const FlowyGrid(), (err) => FlowyErrorPage(err.toString()), ), ); @@ -66,14 +65,14 @@ class _GridPageState extends State { } } -class GridBody extends StatefulWidget { - const GridBody({Key? key}) : super(key: key); +class FlowyGrid extends StatefulWidget { + const FlowyGrid({Key? key}) : super(key: key); @override - _GridBodyState createState() => _GridBodyState(); + _FlowyGridState createState() => _FlowyGridState(); } -class _GridBodyState extends State { +class _FlowyGridState extends State { final _scrollController = GridScrollController(); @override @@ -86,31 +85,28 @@ class _GridBodyState extends State { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - return state.gridInfo.fold( + return state.fields.fold( () => const Center(child: CircularProgressIndicator.adaptive()), - (some) => some.fold( - (gridInfo) => _renderGrid(context, gridInfo), - (err) => FlowyErrorPage(err.toString()), - ), + (fields) => _renderGrid(context, fields), ); }, ); } - Widget _renderGrid(BuildContext context, GridInfo gridInfo) { + Widget _renderGrid(BuildContext context, List fields) { return Stack( children: [ StyledSingleChildScrollView( controller: _scrollController.horizontalController, axis: Axis.horizontal, child: SizedBox( - width: GridLayout.headerWidth(gridInfo.fields), + width: GridLayout.headerWidth(fields), child: CustomScrollView( physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ - _buildHeader(gridInfo.fields), - _buildRows(gridInfo), + _buildHeader(fields), + _buildRows(context), const GridFooter(), ], ), @@ -134,14 +130,14 @@ class _GridBodyState extends State { ); } - Widget _buildRows(GridInfo gridInfo) { + Widget _buildRows(BuildContext context) { return SliverList( delegate: SliverChildBuilderDelegate( (context, index) { - final data = gridInfo.rowAtIndex(index); - return GridRowWidget(data: data); + final rowData = context.read().state.rows[index]; + return GridRowWidget(data: rowData); }, - childCount: gridInfo.numberOfRows(), + childCount: context.read().state.rows.length, addRepaintBoundaries: true, ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 7b183abbe5..2bb1782f13 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -7,20 +8,20 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(CellContext cellContext) { - switch (cellContext.field.fieldType) { +Widget buildGridCell(GridCellData cellData) { + switch (cellData.field.fieldType) { case FieldType.Checkbox: - return CheckboxCell(cellContext: cellContext); + return CheckboxCell(cellData: cellData); case FieldType.DateTime: - return DateCell(cellContext: cellContext); + return DateCell(cellData: cellData); case FieldType.MultiSelect: - return MultiSelectCell(cellContext: cellContext); + return MultiSelectCell(cellContext: cellData); case FieldType.Number: - return NumberCell(cellContext: cellContext); + return NumberCell(cellData: cellData); case FieldType.RichText: - return GridTextCell(cellContext: cellContext); + return GridTextCell(cellData: cellData); case FieldType.SingleSelect: - return SingleSelectCell(cellContext: cellContext); + return SingleSelectCell(cellContext: cellData); default: return const BlankCell(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index ec3e51b102..eec381914a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,14 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const CheckboxCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -21,7 +21,7 @@ class _CheckboxCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index dbe631f2f1..5d9f452c78 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,14 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const DateCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -21,7 +21,7 @@ class _DateCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index c8bd05c3fe..45f5f89c38 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -11,7 +11,7 @@ import 'cell_container.dart'; class GridRowWidget extends StatefulWidget { final GridRowData data; - GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.row.id)); + GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.rowId)); @override State createState() => _GridRowWidgetState(); @@ -37,7 +37,7 @@ class _GridRowWidgetState extends State { onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), child: SizedBox( - height: _rowBloc.state.data.row.height.toDouble(), + height: _rowBloc.state.rowHeight, child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -60,26 +60,17 @@ class _GridRowWidgetState extends State { Widget _buildCells() { return BlocBuilder( - buildWhen: (p, c) => p.data != c.data, + buildWhen: (p, c) => p.cellDatas != c.cellDatas, builder: (context, state) { return Row( - key: ValueKey(state.data.row.id), - children: state.data.fields.map( - (field) { - final cell = state.data.cellMap[field.id]; - return CellContainer( - width: field.width.toDouble(), - child: buildGridCell( - CellContext( - gridId: state.data.gridId, - rowId: state.data.row.id, - field: field, - cell: cell, - ), + children: state.cellDatas + .map( + (cellData) => CellContainer( + width: cellData.field.width.toDouble(), + child: buildGridCell(cellData), ), - ); - }, - ).toList(), + ) + .toList(), ); }, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index c624618ec7..ea3f70fed3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,14 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const NumberCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -21,7 +21,7 @@ class _NumberCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 575815013d..94891924cd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -3,7 +3,7 @@ import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellContext; const SingleSelectCell({ required this.cellContext, @@ -37,7 +37,7 @@ class _SingleSelectCellState extends State { //---------------------------------------------------------------- class MultiSelectCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellContext; const MultiSelectCell({ required this.cellContext, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index c5c330616b..71ab0c41bd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,15 +1,15 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// The interface of base cell. class GridTextCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const GridTextCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -24,7 +24,7 @@ class _GridTextCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); _controller = TextEditingController(text: _cellBloc.state.content); _focusNode.addListener(_focusChanged); super.initState(); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index 10cb8bae79..c13b12e687 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -69,6 +69,23 @@ class GridEventCreateRow { } } +class GridEventGetRow { + QueryRowPayload request; + GridEventGetRow(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetRow.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Row.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventUpdateCell { CellMetaChangeset request; GridEventUpdateCell(this.request); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index 69efeb81b7..02e3e595c5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -41,7 +41,10 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode UserIdInvalid = ErrorCode._(311, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid'); static const ErrorCode UserNotExist = ErrorCode._(312, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist'); static const ErrorCode TextTooLong = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextTooLong'); - static const ErrorCode InvalidData = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); + static const ErrorCode BlockIdIsEmpty = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty'); + static const ErrorCode RowIdIsEmpty = ErrorCode._(402, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); + static const ErrorCode GridIdIsEmpty = ErrorCode._(403, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridIdIsEmpty'); + static const ErrorCode InvalidData = ErrorCode._(404, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); static const $core.List values = [ Internal, @@ -75,6 +78,9 @@ class ErrorCode extends $pb.ProtobufEnum { UserIdInvalid, UserNotExist, TextTooLong, + BlockIdIsEmpty, + RowIdIsEmpty, + GridIdIsEmpty, InvalidData, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 26a0b31029..7a3269aa7f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -43,9 +43,12 @@ const ErrorCode$json = const { const {'1': 'UserIdInvalid', '2': 311}, const {'1': 'UserNotExist', '2': 312}, const {'1': 'TextTooLong', '2': 400}, - const {'1': 'InvalidData', '2': 401}, + const {'1': 'BlockIdIsEmpty', '2': 401}, + const {'1': 'RowIdIsEmpty', '2': 402}, + const {'1': 'GridIdIsEmpty', '2': 403}, + const {'1': 'InvalidData', '2': 404}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhAKC0ludmFsaWREYXRhEJED'); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhMKDkJsb2NrSWRJc0VtcHR5EJEDEhEKDFJvd0lkSXNFbXB0eRCSAxISCg1HcmlkSWRJc0VtcHR5EJMDEhAKC0ludmFsaWREYXRhEJQD'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 9b4dc19b7c..b44a3e7814 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -9,15 +9,13 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'meta.pb.dart' as $0; - import 'meta.pbenum.dart' as $0; class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) - ..pc<$0.GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockOrders', $pb.PbFieldType.PM, subBuilder: GridBlockOrder.create) ..hasRequiredFields = false ; @@ -25,7 +23,7 @@ class Grid extends $pb.GeneratedMessage { factory Grid({ $core.String? id, $core.Iterable? fieldOrders, - $core.Iterable<$0.GridBlockMeta>? blocks, + $core.Iterable? blockOrders, }) { final _result = create(); if (id != null) { @@ -34,8 +32,8 @@ class Grid extends $pb.GeneratedMessage { if (fieldOrders != null) { _result.fieldOrders.addAll(fieldOrders); } - if (blocks != null) { - _result.blocks.addAll(blocks); + if (blockOrders != null) { + _result.blockOrders.addAll(blockOrders); } return _result; } @@ -73,7 +71,7 @@ class Grid extends $pb.GeneratedMessage { $core.List get fieldOrders => $_getList(1); @$pb.TagNumber(3) - $core.List<$0.GridBlockMeta> get blocks => $_getList(2); + $core.List get blockOrders => $_getList(2); } class Field extends $pb.GeneratedMessage { @@ -507,6 +505,47 @@ class Row extends $pb.GeneratedMessage { void clearHeight() => clearField(3); } +class RepeatedRow extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) + ..hasRequiredFields = false + ; + + RepeatedRow._() : super(); + factory RepeatedRow({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedRow create() => RepeatedRow._(); + RepeatedRow createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedRow? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class RepeatedGridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridBlock', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridBlock.create) @@ -548,24 +587,71 @@ class RepeatedGridBlock extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } +class GridBlockOrder extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrder', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..hasRequiredFields = false + ; + + GridBlockOrder._() : super(); + factory GridBlockOrder({ + $core.String? blockId, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + return _result; + } + factory GridBlockOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockOrder.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlockOrder clone() => GridBlockOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockOrder copyWith(void Function(GridBlockOrder) updates) => super.copyWith((message) => updates(message as GridBlockOrder)) as GridBlockOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockOrder create() => GridBlockOrder._(); + GridBlockOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockOrder? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); +} + class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: Row.create) + ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowIds') ..hasRequiredFields = false ; GridBlock._() : super(); factory GridBlock({ $core.String? blockId, - $core.Iterable? rows, + $core.Iterable<$core.String>? rowIds, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rows != null) { - _result.rows.addAll(rows); + if (rowIds != null) { + _result.rowIds.addAll(rowIds); } return _result; } @@ -600,7 +686,7 @@ class GridBlock extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List get rows => $_getList(1); + $core.List<$core.String> get rowIds => $_getList(1); } class Cell extends $pb.GeneratedMessage { @@ -846,34 +932,34 @@ class GridBlockId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } -enum CreateRowPayload_OneOfUpperRowId { - upperRowId, +enum CreateRowPayload_OneOfStartRowId { + startRowId, notSet } class CreateRowPayload extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CreateRowPayload_OneOfUpperRowId> _CreateRowPayload_OneOfUpperRowIdByTag = { - 2 : CreateRowPayload_OneOfUpperRowId.upperRowId, - 0 : CreateRowPayload_OneOfUpperRowId.notSet + static const $core.Map<$core.int, CreateRowPayload_OneOfStartRowId> _CreateRowPayload_OneOfStartRowIdByTag = { + 2 : CreateRowPayload_OneOfStartRowId.startRowId, + 0 : CreateRowPayload_OneOfStartRowId.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateRowPayload', createEmptyInstance: create) ..oo(0, [2]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'upperRowId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowId') ..hasRequiredFields = false ; CreateRowPayload._() : super(); factory CreateRowPayload({ $core.String? gridId, - $core.String? upperRowId, + $core.String? startRowId, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (upperRowId != null) { - _result.upperRowId = upperRowId; + if (startRowId != null) { + _result.startRowId = startRowId; } return _result; } @@ -898,8 +984,8 @@ class CreateRowPayload extends $pb.GeneratedMessage { static CreateRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); static CreateRowPayload? _defaultInstance; - CreateRowPayload_OneOfUpperRowId whichOneOfUpperRowId() => _CreateRowPayload_OneOfUpperRowIdByTag[$_whichOneof(0)]!; - void clearOneOfUpperRowId() => clearField($_whichOneof(0)); + CreateRowPayload_OneOfStartRowId whichOneOfStartRowId() => _CreateRowPayload_OneOfStartRowIdByTag[$_whichOneof(0)]!; + void clearOneOfStartRowId() => clearField($_whichOneof(0)); @$pb.TagNumber(1) $core.String get gridId => $_getSZ(0); @@ -911,13 +997,13 @@ class CreateRowPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.String get upperRowId => $_getSZ(1); + $core.String get startRowId => $_getSZ(1); @$pb.TagNumber(2) - set upperRowId($core.String v) { $_setString(1, v); } + set startRowId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasUpperRowId() => $_has(1); + $core.bool hasStartRowId() => $_has(1); @$pb.TagNumber(2) - void clearUpperRowId() => clearField(2); + void clearStartRowId() => clearField(2); } class QueryFieldPayload extends $pb.GeneratedMessage { @@ -986,21 +1072,21 @@ class QueryFieldPayload extends $pb.GeneratedMessage { class QueryGridBlocksPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryGridBlocksPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..pc<$0.GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockOrders', $pb.PbFieldType.PM, subBuilder: GridBlockOrder.create) ..hasRequiredFields = false ; QueryGridBlocksPayload._() : super(); factory QueryGridBlocksPayload({ $core.String? gridId, - $core.Iterable<$0.GridBlockMeta>? blocks, + $core.Iterable? blockOrders, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (blocks != null) { - _result.blocks.addAll(blocks); + if (blockOrders != null) { + _result.blockOrders.addAll(blockOrders); } return _result; } @@ -1035,6 +1121,81 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.List<$0.GridBlockMeta> get blocks => $_getList(1); + $core.List get blockOrders => $_getList(1); +} + +class QueryRowPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..hasRequiredFields = false + ; + + QueryRowPayload._() : super(); + factory QueryRowPayload({ + $core.String? gridId, + $core.String? blockId, + $core.String? rowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (blockId != null) { + _result.blockId = blockId; + } + if (rowId != null) { + _result.rowId = rowId; + } + return _result; + } + factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static QueryRowPayload create() => QueryRowPayload._(); + QueryRowPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryRowPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get blockId => $_getSZ(1); + @$pb.TagNumber(2) + set blockId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasBlockId() => $_has(1); + @$pb.TagNumber(2) + void clearBlockId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get rowId => $_getSZ(2); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(2); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 97d52d827f..c4d79ccb0b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -14,12 +14,12 @@ const Grid$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, + const {'1': 'block_orders', '3': 3, '4': 3, '5': 11, '6': '.GridBlockOrder', '10': 'blockOrders'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxImCgZibG9ja3MYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIyCgxibG9ja19vcmRlcnMYAyADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM='); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', @@ -110,6 +110,16 @@ const Row_CellByFieldIdEntry$json = const { /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use repeatedRowDescriptor instead') +const RepeatedRow$json = const { + '1': 'RepeatedRow', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); @$core.Deprecated('Use repeatedGridBlockDescriptor instead') const RepeatedGridBlock$json = const { '1': 'RepeatedGridBlock', @@ -120,17 +130,27 @@ const RepeatedGridBlock$json = const { /// Descriptor for `RepeatedGridBlock`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedGridBlockDescriptor = $convert.base64Decode('ChFSZXBlYXRlZEdyaWRCbG9jaxIgCgVpdGVtcxgBIAMoCzIKLkdyaWRCbG9ja1IFaXRlbXM='); +@$core.Deprecated('Use gridBlockOrderDescriptor instead') +const GridBlockOrder$json = const { + '1': 'GridBlockOrder', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + ], +}; + +/// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZA=='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.Row', '10': 'rows'}, + const {'1': 'row_ids', '3': 2, '4': 3, '5': 9, '10': 'rowIds'}, ], }; /// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSGAoEcm93cxgCIAMoCzIELlJvd1IEcm93cw=='); +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSFwoHcm93X2lkcxgCIAMoCVIGcm93SWRz'); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', @@ -187,15 +207,15 @@ const CreateRowPayload$json = const { '1': 'CreateRowPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'upper_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'upperRowId'}, + const {'1': 'start_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'startRowId'}, ], '8': const [ - const {'1': 'one_of_upper_row_id'}, + const {'1': 'one_of_start_row_id'}, ], }; /// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgx1cHBlcl9yb3dfaWQYAiABKAlIAFIKdXBwZXJSb3dJZEIVChNvbmVfb2ZfdXBwZXJfcm93X2lk'); +final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk'); @$core.Deprecated('Use queryFieldPayloadDescriptor instead') const QueryFieldPayload$json = const { '1': 'QueryFieldPayload', @@ -212,9 +232,21 @@ const QueryGridBlocksPayload$json = const { '1': 'QueryGridBlocksPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'blocks', '3': 2, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, + const {'1': 'block_orders', '3': 2, '4': 3, '5': 11, '6': '.GridBlockOrder', '10': 'blockOrders'}, ], }; /// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBImCgZibG9ja3MYAiADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); +final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM='); +@$core.Deprecated('Use queryRowPayloadDescriptor instead') +const QueryRowPayload$json = const { + '1': 'QueryRowPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + ], +}; + +/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 0a3cba6be6..4bbeae52a5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blocks, + $core.Iterable? blockMetas, }) { final _result = create(); if (gridId != null) { @@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage { if (fields != null) { _result.fields.addAll(fields); } - if (blocks != null) { - _result.blocks.addAll(blocks); + if (blockMetas != null) { + _result.blockMetas.addAll(blockMetas); } return _result; } @@ -73,7 +73,7 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); + $core.List get blockMetas => $_getList(2); } class GridBlockMeta extends $pb.GeneratedMessage { @@ -151,15 +151,15 @@ class GridBlockMeta extends $pb.GeneratedMessage { void clearRowCount() => clearField(3); } -class GridBlockMetaData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) +class GridBlockMetaSerde extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaSerde', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..hasRequiredFields = false ; - GridBlockMetaData._() : super(); - factory GridBlockMetaData({ + GridBlockMetaSerde._() : super(); + factory GridBlockMetaSerde({ $core.String? blockId, $core.Iterable? rowMetas, }) { @@ -172,26 +172,26 @@ class GridBlockMetaData extends $pb.GeneratedMessage { } return _result; } - factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlockMetaSerde.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMetaSerde.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this); + GridBlockMetaSerde clone() => GridBlockMetaSerde()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use + GridBlockMetaSerde copyWith(void Function(GridBlockMetaSerde) updates) => super.copyWith((message) => updates(message as GridBlockMetaSerde)) as GridBlockMetaSerde; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GridBlockMetaData create() => GridBlockMetaData._(); - GridBlockMetaData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlockMetaSerde create() => GridBlockMetaSerde._(); + GridBlockMetaSerde createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlockMetaData? _defaultInstance; + static GridBlockMetaSerde getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMetaSerde? _defaultInstance; @$pb.TagNumber(1) $core.String get blockId => $_getSZ(0); @@ -1020,26 +1020,26 @@ class CellMetaChangeset extends $pb.GeneratedMessage { class BuildGridContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlockMeta.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMetaData', subBuilder: GridBlockMetaData.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', subBuilder: GridBlockMeta.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaSerde.create) ..hasRequiredFields = false ; BuildGridContext._() : super(); factory BuildGridContext({ $core.Iterable? fieldMetas, - GridBlockMeta? gridBlock, - GridBlockMetaData? gridBlockMetaData, + GridBlockMeta? blockMetas, + GridBlockMetaSerde? blockMetaData, }) { final _result = create(); if (fieldMetas != null) { _result.fieldMetas.addAll(fieldMetas); } - if (gridBlock != null) { - _result.gridBlock = gridBlock; + if (blockMetas != null) { + _result.blockMetas = blockMetas; } - if (gridBlockMetaData != null) { - _result.gridBlockMetaData = gridBlockMetaData; + if (blockMetaData != null) { + _result.blockMetaData = blockMetaData; } return _result; } @@ -1068,25 +1068,25 @@ class BuildGridContext extends $pb.GeneratedMessage { $core.List get fieldMetas => $_getList(0); @$pb.TagNumber(2) - GridBlockMeta get gridBlock => $_getN(1); + GridBlockMeta get blockMetas => $_getN(1); @$pb.TagNumber(2) - set gridBlock(GridBlockMeta v) { setField(2, v); } + set blockMetas(GridBlockMeta v) { setField(2, v); } @$pb.TagNumber(2) - $core.bool hasGridBlock() => $_has(1); + $core.bool hasBlockMetas() => $_has(1); @$pb.TagNumber(2) - void clearGridBlock() => clearField(2); + void clearBlockMetas() => clearField(2); @$pb.TagNumber(2) - GridBlockMeta ensureGridBlock() => $_ensure(1); + GridBlockMeta ensureBlockMetas() => $_ensure(1); @$pb.TagNumber(3) - GridBlockMetaData get gridBlockMetaData => $_getN(2); + GridBlockMetaSerde get blockMetaData => $_getN(2); @$pb.TagNumber(3) - set gridBlockMetaData(GridBlockMetaData v) { setField(3, v); } + set blockMetaData(GridBlockMetaSerde v) { setField(3, v); } @$pb.TagNumber(3) - $core.bool hasGridBlockMetaData() => $_has(2); + $core.bool hasBlockMetaData() => $_has(2); @$pb.TagNumber(3) - void clearGridBlockMetaData() => clearField(3); + void clearBlockMetaData() => clearField(3); @$pb.TagNumber(3) - GridBlockMetaData ensureGridBlockMetaData() => $_ensure(2); + GridBlockMetaSerde ensureBlockMetaData() => $_ensure(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 7048fb3c81..d20b9da3f5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,12 +29,12 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, + const {'1': 'block_metas', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz'); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSLwoLYmxvY2tfbWV0YXMYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgpibG9ja01ldGFz'); @$core.Deprecated('Use gridBlockMetaDescriptor instead') const GridBlockMeta$json = const { '1': 'GridBlockMeta', @@ -47,17 +47,17 @@ const GridBlockMeta$json = const { /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); -@$core.Deprecated('Use gridBlockMetaDataDescriptor instead') -const GridBlockMetaData$json = const { - '1': 'GridBlockMetaData', +@$core.Deprecated('Use gridBlockMetaSerdeDescriptor instead') +const GridBlockMetaSerde$json = const { + '1': 'GridBlockMetaSerde', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'}, ], }; -/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw=='); +/// Descriptor for `GridBlockMetaSerde`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaSerdeDescriptor = $convert.base64Decode('ChJHcmlkQmxvY2tNZXRhU2VyZGUSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSJQoJcm93X21ldGFzGAIgAygLMgguUm93TWV0YVIIcm93TWV0YXM='); @$core.Deprecated('Use fieldMetaDescriptor instead') const FieldMeta$json = const { '1': 'FieldMeta', @@ -197,10 +197,10 @@ const BuildGridContext$json = const { '1': 'BuildGridContext', '2': const [ const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, - const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlock'}, - const {'1': 'grid_block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'gridBlockMetaData'}, + const {'1': 'block_metas', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, + const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaSerde', '10': 'blockMetaData'}, ], }; /// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmdyaWRfYmxvY2sYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglncmlkQmxvY2sSQwoUZ3JpZF9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVIRZ3JpZEJsb2NrTWV0YURhdGE='); +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi8KC2Jsb2NrX21ldGFzGAIgASgLMg4uR3JpZEJsb2NrTWV0YVIKYmxvY2tNZXRhcxI7Cg9ibG9ja19tZXRhX2RhdGEYAyABKAsyEy5HcmlkQmxvY2tNZXRhU2VyZGVSDWJsb2NrTWV0YURhdGE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 54f33ea020..f68b10f292 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -12,12 +12,14 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); static const GridNotification GridDidUpdateBlock = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateBlock'); + static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock'); static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); static const $core.List values = [ Unknown, GridDidUpdateBlock, + GridDidCreateBlock, GridDidUpdateCells, GridDidUpdateFields, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 4c4ff69eb1..b266e63e09 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -14,10 +14,11 @@ const GridNotification$json = const { '2': const [ const {'1': 'Unknown', '2': 0}, const {'1': 'GridDidUpdateBlock', '2': 10}, + const {'1': 'GridDidCreateBlock', '2': 11}, const {'1': 'GridDidUpdateCells', '2': 20}, const {'1': 'GridDidUpdateFields', '2': 30}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 787f44e52c..91a3861076 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -12,15 +12,17 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetGridData = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridData'); static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks'); - static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); - static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); - static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); + static const GridEvent CreateRow = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent GetRow = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); + static const GridEvent UpdateCell = GridEvent._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, GetGridBlocks, GetFields, CreateRow, + GetRow, UpdateCell, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 707eca7c61..c203b10c75 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -14,11 +14,12 @@ const GridEvent$json = const { '2': const [ const {'1': 'GetGridData', '2': 0}, const {'1': 'GetGridBlocks', '2': 1}, - const {'1': 'GetFields', '2': 2}, - const {'1': 'CreateRow', '2': 3}, - const {'1': 'UpdateCell', '2': 4}, + const {'1': 'GetFields', '2': 10}, + const {'1': 'CreateRow', '2': 11}, + const {'1': 'GetRow', '2': 12}, + const {'1': 'UpdateCell', '2': 20}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDQoJQ3JlYXRlUm93EAsSCgoGR2V0Um93EAwSDgoKVXBkYXRlQ2VsbBAU'); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 30aa28a798..929fcad90c 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1088,6 +1088,7 @@ version = "0.1.0" dependencies = [ "bytes", "flowy-derive", + "flowy-error-code", "lib-infra", "protobuf", "serde", diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 96755db623..046fd85668 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default staticlib -crate-type = ["staticlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 8921d15aea..d6022769fb 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,9 +1,10 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, RepeatedField, - RepeatedGridBlock, Row, + CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, + QueryRowPayload, RepeatedField, RepeatedGridBlock, RepeatedRow, Row, }; +use flowy_grid_data_model::parser::{CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -23,20 +24,38 @@ pub(crate) async fn get_grid_blocks_handler( data: Data, manager: AppData>, ) -> DataResult { - let payload: QueryGridBlocksPayload = data.into_inner(); - let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_grid_block = editor.get_grid_blocks(Some(payload.blocks)).await?; + let params: QueryGridBlocksParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let block_ids = params + .block_orders + .into_iter() + .map(|block| block.block_id) + .collect::>(); + let repeated_grid_block = editor.get_blocks(Some(block_ids)).await?; data_result(repeated_grid_block) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn get_row_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: QueryRowParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_row(¶ms.block_id, ¶ms.row_id).await? { + None => Err(FlowyError::record_not_found().context("Can not find the row")), + Some(row) => data_result(row), + } +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_fields_handler( data: Data, manager: AppData>, ) -> DataResult { - let payload: QueryFieldPayload = data.into_inner(); - let editor = manager.get_grid_editor(&payload.grid_id)?; - let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?; + let params: QueryFieldParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let field_metas = editor.get_field_metas(Some(params.field_orders)).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); data_result(repeated_field) } @@ -46,9 +65,9 @@ pub(crate) async fn create_row_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let payload: CreateRowPayload = data.into_inner(); - let editor = manager.get_grid_editor(payload.grid_id.as_ref())?; - let _ = editor.create_row(payload.upper_row_id).await?; + let params: CreateRowParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(params.grid_id.as_ref())?; + let _ = editor.create_row(params.start_row_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index d748b3b882..03b27f4c70 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -12,6 +12,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::CreateRow, create_row_handler) + .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); module @@ -27,11 +28,14 @@ pub enum GridEvent { GetGridBlocks = 1, #[event(input = "QueryFieldPayload", output = "RepeatedField")] - GetFields = 2, + GetFields = 10, #[event(input = "CreateRowPayload", output = "Row")] - CreateRow = 3, + CreateRow = 11, + + #[event(input = "QueryRowPayload", output = "Row")] + GetRow = 12, #[event(input = "CellMetaChangeset")] - UpdateCell = 4, + UpdateCell = 20, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 7afcdf05fd..104f74d5f4 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -182,11 +182,11 @@ pub async fn make_grid_view_data( grid_manager: Arc, build_context: BuildGridContext, ) -> FlowyResult { - let block_id = build_context.grid_block.block_id.clone(); + let block_id = build_context.block_metas.block_id.clone(); let grid_meta = GridMeta { grid_id: view_id.to_string(), fields: build_context.field_metas, - blocks: vec![build_context.grid_block], + block_metas: vec![build_context.block_metas], }; let grid_meta_delta = make_grid_delta(&grid_meta); @@ -195,7 +195,7 @@ pub async fn make_grid_view_data( Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); let _ = grid_manager.create_grid(view_id, repeated_revision).await?; - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); + let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into(); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index a4f7fbb46c..72b3f12abd 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -27,6 +27,7 @@ pub enum GridNotification { Unknown = 0, GridDidUpdateBlock = 10, + GridDidCreateBlock = 11, GridDidUpdateCells = 20, GridDidUpdateFields = 30, } @@ -40,6 +41,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), 10 => ::std::option::Option::Some(GridNotification::GridDidUpdateBlock), + 11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock), 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), _ => ::std::option::Option::None @@ -50,6 +52,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { static values: &'static [GridNotification] = &[ GridNotification::Unknown, GridNotification::GridDidUpdateBlock, + GridNotification::GridDidCreateBlock, GridNotification::GridDidUpdateCells, GridNotification::GridDidUpdateFields, ]; @@ -80,9 +83,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*h\n\x10GridNotification\x12\x0b\n\x07Unkno\ - wn\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12GridDidUpdat\ - eCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\x06proto3\ + \n\x17dart_notification.proto*\x80\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12Gri\ + dDidCreateBlock\x10\x0b\x12\x16\n\x12GridDidUpdateCells\x10\x14\x12\x17\ + \n\x13GridDidUpdateFields\x10\x1eb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 1ed38366d4..9feb87fec5 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -27,9 +27,10 @@ pub enum GridEvent { GetGridData = 0, GetGridBlocks = 1, - GetFields = 2, - CreateRow = 3, - UpdateCell = 4, + GetFields = 10, + CreateRow = 11, + GetRow = 12, + UpdateCell = 20, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -41,9 +42,10 @@ impl ::protobuf::ProtobufEnum for GridEvent { match value { 0 => ::std::option::Option::Some(GridEvent::GetGridData), 1 => ::std::option::Option::Some(GridEvent::GetGridBlocks), - 2 => ::std::option::Option::Some(GridEvent::GetFields), - 3 => ::std::option::Option::Some(GridEvent::CreateRow), - 4 => ::std::option::Option::Some(GridEvent::UpdateCell), + 10 => ::std::option::Option::Some(GridEvent::GetFields), + 11 => ::std::option::Option::Some(GridEvent::CreateRow), + 12 => ::std::option::Option::Some(GridEvent::GetRow), + 20 => ::std::option::Option::Some(GridEvent::UpdateCell), _ => ::std::option::Option::None } } @@ -54,6 +56,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetGridBlocks, GridEvent::GetFields, GridEvent::CreateRow, + GridEvent::GetRow, GridEvent::UpdateCell, ]; values @@ -83,9 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*]\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ - \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreate\ - Row\x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\ + \n\x0fevent_map.proto*i\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ + \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\r\n\tCreateRo\ + w\x10\x0b\x12\n\n\x06GetRow\x10\x0c\x12\x0e\n\nUpdateCell\x10\x14b\x06pr\ + oto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 9aadc14372..0262b34477 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -3,6 +3,7 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; GridDidUpdateBlock = 10; + GridDidCreateBlock = 11; GridDidUpdateCells = 20; GridDidUpdateFields = 30; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index a5c998e7e1..6c39e618f5 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -3,7 +3,8 @@ syntax = "proto3"; enum GridEvent { GetGridData = 0; GetGridBlocks = 1; - GetFields = 2; - CreateRow = 3; - UpdateCell = 4; + GetFields = 10; + CreateRow = 11; + GetRow = 12; + UpdateCell = 20; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 21046c295c..f8ba93b906 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,14 +1,15 @@ use crate::manager::GridUser; -use crate::services::row::{make_cell, make_grid_blocks, make_row_ids_per_block, GridBlockMetaDataSnapshot}; +use crate::services::row::{make_cell, make_row_ids_per_block, GridBlockMetaData}; use bytes::Bytes; +use crate::dart_notification::{send_dart_notification, GridNotification}; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridBlockMetaDataChange, GridBlockMetaDataPad}; +use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, + FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -17,10 +18,7 @@ use flowy_sync::{ }; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; - use std::collections::HashMap; - -use crate::dart_notification::{send_dart_notification, GridNotification}; use std::sync::Arc; use tokio::sync::RwLock; @@ -30,7 +28,7 @@ type BlockId = String; pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, - editor_map: DashMap>, + editor_map: DashMap>, block_id_by_row_id: DashMap, } @@ -49,7 +47,7 @@ impl GridBlockMetaEditorManager { Ok(manager) } - pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { match self.editor_map.get(block_id) { None => { tracing::error!("The is a fatal error, block is not exist"); @@ -124,6 +122,16 @@ impl GridBlockMetaEditorManager { Ok(()) } + pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult>> { + let editor = self.get_editor(block_id).await?; + let mut row_metas = editor.get_row_metas(Some(vec![row_id.to_owned()])).await?; + if row_metas.is_empty() { + Ok(None) + } else { + Ok(row_metas.pop()) + } + } + pub async fn update_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; @@ -131,10 +139,10 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub(crate) async fn get_block_meta_snapshot_from_blocks( + pub(crate) async fn get_block_meta_data_from_blocks( &self, grid_blocks: Vec, - ) -> FlowyResult> { + ) -> FlowyResult> { let mut snapshots = vec![]; for grid_block in grid_blocks { let editor = self.get_editor(&grid_block.block_id).await?; @@ -144,7 +152,7 @@ impl GridBlockMetaEditorManager { .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - snapshots.push(GridBlockMetaDataSnapshot { + snapshots.push(GridBlockMetaData { block_id: grid_block.block_id, row_metas, }); @@ -152,20 +160,17 @@ impl GridBlockMetaEditorManager { Ok(snapshots) } - pub(crate) async fn get_block_meta_snapshot_from_row_orders( - &self, - grid_block_metas: &Vec, - ) -> FlowyResult> { + pub(crate) async fn get_block_meta_data(&self, block_ids: &[String]) -> FlowyResult> { let mut snapshots = vec![]; - for grid_block_meta in grid_block_metas { - let editor = self.get_editor(&grid_block_meta.block_id).await?; + for block_id in block_ids { + let editor = self.get_editor(&block_id).await?; let row_metas = editor.get_row_metas(None).await?; row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - snapshots.push(GridBlockMetaDataSnapshot { - block_id: grid_block_meta.block_id.clone(), + snapshots.push(GridBlockMetaData { + block_id: block_id.clone(), row_metas, }); } @@ -182,7 +187,7 @@ impl GridBlockMetaEditorManager { Ok(row_orders) } - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { match self.block_id_by_row_id.get(row_id) { None => { let msg = format!( @@ -237,7 +242,7 @@ impl GridBlockMetaEditorManager { async fn make_block_meta_editor_map( user: &Arc, blocks: Vec, -) -> FlowyResult>> { +) -> FlowyResult>> { let editor_map = DashMap::new(); for block in blocks { let editor = make_block_meta_editor(user, &block.block_id).await?; @@ -247,10 +252,7 @@ async fn make_block_meta_editor_map( Ok(editor_map) } -async fn make_block_meta_editor( - user: &Arc, - block_id: &str, -) -> FlowyResult { +async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { let token = user.token()?; let user_id = user.user_id()?; let pool = user.db_pool()?; @@ -258,17 +260,17 @@ async fn make_block_meta_editor( let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache)); let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence); - ClientGridBlockMetaDataEditor::new(&user_id, &token, block_id, rev_manager).await + ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await } -pub struct ClientGridBlockMetaDataEditor { +pub struct ClientGridBlockMetaEditor { user_id: String, pub block_id: String, - pad: Arc>, + pad: Arc>, rev_manager: Arc, } -impl ClientGridBlockMetaDataEditor { +impl ClientGridBlockMetaEditor { pub async fn new( user_id: &str, token: &str, @@ -340,7 +342,7 @@ impl ClientGridBlockMetaDataEditor { async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridBlockMetaDataPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, { let mut write_guard = self.pad.write().await; match f(&mut *write_guard)? { @@ -352,8 +354,8 @@ impl ClientGridBlockMetaDataEditor { Ok(()) } - async fn apply_change(&self, change: GridBlockMetaDataChange) -> FlowyResult<()> { - let GridBlockMetaDataChange { delta, md5 } = change; + async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> { + let GridBlockMetaChange { delta, md5 } = change; let user_id = self.user_id.clone(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let delta_data = delta.to_delta_bytes(); @@ -387,10 +389,10 @@ impl RevisionCloudService for GridBlockMetaRevisionCloudService { struct GridBlockMetaPadBuilder(); impl RevisionObjectBuilder for GridBlockMetaPadBuilder { - type Output = GridBlockMetaDataPad; + type Output = GridBlockMetaPad; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridBlockMetaDataPad::from_revisions(object_id, revisions)?; + let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?; Ok(pad) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index f991d26a10..8f4d82d992 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -7,14 +7,15 @@ use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, - RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, + GridBlockOrder, RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, + RowMetaChangeset, }; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ - make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, row_meta_from_context, - serialize_cell_data, GridBlockMetaDataSnapshot, RowMetaContext, RowMetaContextBuilder, + make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, make_rows_from_row_metas, + row_meta_from_context, serialize_cell_data, GridBlockMetaData, RowMetaContext, RowMetaContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -125,6 +126,33 @@ impl ClientGridEditor { self.block_meta_manager.update_row(changeset).await } + pub async fn get_rows(&self, block_id: &str) -> FlowyResult { + let block_ids = vec![block_id.to_owned()]; + let mut block_meta_data_vec = self.get_block_meta_data_vec(Some(&block_ids)).await?; + debug_assert_eq!(block_meta_data_vec.len(), 1); + if block_meta_data_vec.len() == 1 { + let block_meta_data = block_meta_data_vec.pop().unwrap(); + let field_metas = self.get_field_metas(None).await?; + let rows = make_rows_from_row_metas(&field_metas, &block_meta_data.row_metas); + Ok(rows.into()) + } else { + Ok(vec![].into()) + } + } + + pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult> { + match self.block_meta_manager.get_row(block_id, row_id).await? { + None => Ok(None), + Some(row) => { + let field_metas = self.get_field_metas(None).await?; + let row_metas = vec![row]; + let mut rows = make_rows_from_row_metas(&field_metas, &row_metas); + debug_assert!(rows.len() == 1); + Ok(rows.pop()) + } + } + } + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { if let Some(cell_data) = changeset.data.as_ref() { match self.pad.read().await.get_field(&changeset.field_id) { @@ -147,41 +175,17 @@ impl ClientGridEditor { Ok(()) } - pub async fn get_grid_blocks( - &self, - grid_block_metas: Option>, - ) -> FlowyResult { - let grid_block_meta_snapshots = self.get_grid_block_meta_snapshots(grid_block_metas.as_ref()).await?; - let field_meta = self.pad.read().await.get_field_metas(None)?; - match grid_block_metas { - None => make_grid_blocks(&field_meta, grid_block_meta_snapshots), - Some(grid_block_metas) => { - make_grid_block_from_block_metas(&field_meta, grid_block_metas, grid_block_meta_snapshots) - } + pub async fn get_blocks(&self, block_ids: Option>) -> FlowyResult { + let block_meta_data_vec = self.get_block_meta_data_vec(block_ids.as_ref()).await?; + match block_ids { + None => make_grid_blocks(block_meta_data_vec), + Some(block_ids) => make_grid_block_from_block_metas(&block_ids, block_meta_data_vec), } } - pub(crate) async fn get_grid_block_meta_snapshots( - &self, - grid_block_infos: Option<&Vec>, - ) -> FlowyResult> { - match grid_block_infos { - None => { - let grid_blocks = self.pad.read().await.get_blocks(); - let row_metas_per_block = self - .block_meta_manager - .get_block_meta_snapshot_from_blocks(grid_blocks) - .await?; - Ok(row_metas_per_block) - } - Some(grid_block_infos) => { - let row_metas_per_block = self - .block_meta_manager - .get_block_meta_snapshot_from_row_orders(grid_block_infos) - .await?; - Ok(row_metas_per_block) - } - } + pub async fn get_block_metas(&self) -> FlowyResult> { + let grid_blocks = self.pad.read().await.get_blocks(); + Ok(grid_blocks) } pub async fn delete_rows(&self, row_ids: Vec) -> FlowyResult<()> { @@ -194,11 +198,20 @@ impl ClientGridEditor { pub async fn grid_data(&self) -> FlowyResult { let field_orders = self.pad.read().await.get_field_orders(); - let block_orders = self.pad.read().await.get_blocks(); + let block_orders = self + .pad + .read() + .await + .get_blocks() + .into_iter() + .map(|grid_block_meta| GridBlockOrder { + block_id: grid_block_meta.block_id, + }) + .collect::>(); Ok(Grid { id: self.grid_id.clone(), field_orders, - blocks: block_orders, + block_orders, }) } @@ -207,9 +220,27 @@ impl ClientGridEditor { Ok(field_meta) } - pub async fn get_blocks(&self) -> FlowyResult> { - let grid_blocks = self.pad.read().await.get_blocks(); - Ok(grid_blocks) + pub async fn get_block_meta_data_vec( + &self, + block_ids: Option<&Vec>, + ) -> FlowyResult> { + match block_ids { + None => { + let grid_blocks = self.pad.read().await.get_blocks(); + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_data_from_blocks(grid_blocks) + .await?; + Ok(row_metas_per_block) + } + Some(block_ids) => { + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_data(block_ids.as_slice()) + .await?; + Ok(row_metas_per_block) + } + } } pub async fn delta_bytes(&self) -> Bytes { diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 953a950917..8d1e683a6e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,11 +1,11 @@ use crate::services::row::deserialize_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - Cell, CellMeta, FieldMeta, GridBlock, GridBlockMeta, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, + Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; -use std::ops::Deref; + use std::sync::Arc; pub(crate) struct RowIdsPerBlock { @@ -22,9 +22,9 @@ impl RowIdsPerBlock { } } -pub(crate) struct GridBlockMetaDataSnapshot { +pub struct GridBlockMetaData { pub(crate) block_id: String, - pub(crate) row_metas: Vec>, + pub row_metas: Vec>, } pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { @@ -40,17 +40,14 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec>() } -pub(crate) fn make_grid_blocks( - field_metas: &[FieldMeta], - grid_block_meta_snapshots: Vec, -) -> FlowyResult { - Ok(grid_block_meta_snapshots +pub(crate) fn make_grid_blocks(block_meta_snapshots: Vec) -> FlowyResult { + Ok(block_meta_snapshots .into_iter() .map(|row_metas_per_block| { - let rows = make_rows_from_row_metas(field_metas, &row_metas_per_block.row_metas); + let row_ids = make_row_ids_from_row_metas(&row_metas_per_block.row_metas); GridBlock { block_id: row_metas_per_block.block_id, - rows, + row_ids, } }) .collect::>() @@ -76,6 +73,10 @@ pub fn make_cell( } } +pub(crate) fn make_row_ids_from_row_metas(row_metas: &Vec>) -> Vec { + row_metas.iter().map(|row_meta| row_meta.id.clone()).collect::>() +} + pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>) -> Vec { let field_meta_map = fields .iter() @@ -101,22 +102,21 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec, - grid_block_meta_snapshots: Vec, + block_ids: &[String], + block_meta_data_vec: Vec, ) -> FlowyResult { - let block_meta_snapshot_map: HashMap<&String, &Vec>> = grid_block_meta_snapshots + let block_meta_data_map: HashMap<&String, &Vec>> = block_meta_data_vec .iter() - .map(|snapshot| (&snapshot.block_id, &snapshot.row_metas)) + .map(|data| (&data.block_id, &data.row_metas)) .collect(); let mut grid_blocks = vec![]; - for grid_block_meta in grid_block_metas { - match block_meta_snapshot_map.get(&grid_block_meta.block_id) { + for block_id in block_ids { + match block_meta_data_map.get(&block_id) { None => {} Some(row_metas) => { - let rows = make_rows_from_row_metas(&field_metas, row_metas); - grid_blocks.push(GridBlock::new(&grid_block_meta.block_id, rows)); + let row_ids = make_row_ids_from_row_metas(row_metas); + grid_blocks.push(GridBlock::new(block_id, row_ids)); } } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 20164bca37..571ca1ab95 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -89,8 +89,8 @@ impl GridEditorTest { let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let field_metas = editor.get_field_metas(None).await.unwrap(); - let grid_blocks = editor.get_blocks().await.unwrap(); - let row_metas = editor.get_grid_block_meta_snapshots(None).await.unwrap(); + let grid_blocks = editor.get_block_metas().await.unwrap(); + let row_metas = get_row_metas(&editor).await; let grid_id = test.view.id; Self { @@ -150,13 +150,13 @@ impl GridEditorTest { } EditorScript::CreateBlock { block } => { self.editor.create_block(block).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::UpdateBlock { changeset: change } => { self.editor.update_block(change).await.unwrap(); } EditorScript::AssertBlockCount(count) => { - assert_eq!(self.editor.get_blocks().await.unwrap().len(), count); + assert_eq!(self.editor.get_block_metas().await.unwrap().len(), count); } EditorScript::AssertBlock { block_index, @@ -167,25 +167,25 @@ impl GridEditorTest { assert_eq!(self.grid_blocks[block_index].start_row_index, start_row_index); } EditorScript::AssertBlockEqual { block_index, block } => { - let blocks = self.editor.get_blocks().await.unwrap(); + let blocks = self.editor.get_block_metas().await.unwrap(); let compared_block = blocks[block_index].clone(); assert_eq!(compared_block, block); } EditorScript::CreateEmptyRow => { self.editor.create_row(None).await.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.row_metas = self.get_row_metas().await; + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::CreateRow { context } => { self.editor.insert_rows(vec![context]).await.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.row_metas = self.get_row_metas().await; + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { self.editor.delete_rows(row_ids).await.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.row_metas = self.get_row_metas().await; + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::AssertRow { changeset } => { let row = self.row_metas.iter().find(|row| row.id == changeset.row_id).unwrap(); @@ -204,11 +204,11 @@ impl GridEditorTest { assert!(result.is_err()) } else { let _ = result.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); + self.row_metas = self.get_row_metas().await; } } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_grid_blocks(None).await.unwrap().len(), count); + assert_eq!(self.row_metas.len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; @@ -218,6 +218,20 @@ impl GridEditorTest { } } } + + async fn get_row_metas(&self) -> Vec> { + get_row_metas(&self.editor).await + } +} + +async fn get_row_metas(editor: &Arc) -> Vec> { + editor + .get_block_meta_data_vec(None) + .await + .unwrap() + .pop() + .unwrap() + .row_metas } pub fn create_text_field() -> FieldMeta { diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 3c859d28f0..a4cde5ddf2 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -485,6 +485,7 @@ version = "0.1.0" dependencies = [ "bytes", "flowy-derive", + "flowy-error-code", "lib-infra", "protobuf", "serde", diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs similarity index 79% rename from shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs rename to shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs index dd62c787d3..7bfef998c2 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMetaData, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{GridBlockMetaSerde, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; @@ -12,19 +12,22 @@ pub type GridBlockMetaDelta = PlainTextDelta; pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GridBlockMetaDataPad { +pub struct GridBlockMetaPad { block_id: String, - rows: Vec>, + row_metas: Vec>, #[serde(skip)] pub(crate) delta: GridBlockMetaDelta, } -impl GridBlockMetaDataPad { +impl GridBlockMetaPad { pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_meta: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { - CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) + tracing::info!("delta: {}", delta); + tracing::info!("{}", s); + let block_meta: GridBlockMetaSerde = serde_json::from_str(&s).map_err(|e| { + let msg = format!("Deserialize delta to block meta failed: {}", e); + CollaborateError::internal().context(msg) })?; let block_id = block_meta.block_id; let rows = block_meta @@ -32,7 +35,11 @@ impl GridBlockMetaDataPad { .into_iter() .map(Arc::new) .collect::>>(); - Ok(Self { block_id, rows, delta }) + Ok(Self { + block_id, + row_metas: rows, + delta, + }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { @@ -44,7 +51,7 @@ impl GridBlockMetaDataPad { &mut self, row: RowMeta, start_row_id: Option, - ) -> CollaborateResult> { + ) -> CollaborateResult> { self.modify(|rows| { if let Some(upper_row_id) = start_row_id { if upper_row_id.is_empty() { @@ -63,7 +70,7 @@ impl GridBlockMetaDataPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify(|rows| { rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) @@ -72,10 +79,10 @@ impl GridBlockMetaDataPad { pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { match row_ids { - None => Ok(self.rows.to_vec()), + None => Ok(self.row_metas.to_vec()), Some(row_ids) => { let row_map = self - .rows + .row_metas .iter() .map(|row| (&row.id, row.clone())) .collect::>>(); @@ -95,10 +102,10 @@ impl GridBlockMetaDataPad { } pub fn number_of_rows(&self) -> i32 { - self.rows.len() as i32 + self.row_metas.len() as i32 } - pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { let mut is_changed = None; @@ -123,12 +130,12 @@ impl GridBlockMetaDataPad { }) } - pub fn modify(&mut self, f: F) -> CollaborateResult> + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { let cloned_self = self.clone(); - match f(&mut self.rows)? { + match f(&mut self.row_metas)? { None => Ok(None), Some(_) => { let old = cloned_self.to_json()?; @@ -137,14 +144,14 @@ impl GridBlockMetaDataPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(GridBlockMetaDataChange { delta, md5: self.md5() })) + Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } } } } } - fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut RowMeta) -> CollaborateResult>, { @@ -172,35 +179,35 @@ impl GridBlockMetaDataPad { } } -pub struct GridBlockMetaDataChange { +pub struct GridBlockMetaChange { pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta { +pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaSerde) -> GridBlockMetaDelta { let json = serde_json::to_string(&grid_block_meta_data).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision { +pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaSerde) -> RepeatedRevision { let delta = make_block_meta_delta(grid_block_meta_data); let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes); revision.into() } -impl std::default::Default for GridBlockMetaDataPad { +impl std::default::Default for GridBlockMetaPad { fn default() -> Self { - let block_meta_data = GridBlockMetaData { + let block_meta_data = GridBlockMetaSerde { block_id: uuid(), row_metas: vec![], }; let delta = make_block_meta_delta(&block_meta_data); - GridBlockMetaDataPad { + GridBlockMetaPad { block_id: block_meta_data.block_id, - rows: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), + row_metas: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), delta, } } @@ -208,7 +215,7 @@ impl std::default::Default for GridBlockMetaDataPad { #[cfg(test)] mod tests { - use crate::client_grid::{GridBlockMetaDataPad, GridBlockMetaDelta}; + use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; #[test] @@ -225,7 +232,7 @@ mod tests { let change = pad.add_row(row, None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); } @@ -239,27 +246,27 @@ mod tests { let change = pad.add_row(row_1.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row(row_2.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":101},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":106},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":109},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# + r#"[{"retain":114},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# ); - assert_eq!(*pad.rows[0], row_1); - assert_eq!(*pad.rows[1], row_3); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.row_metas[0], row_1); + assert_eq!(*pad.row_metas[1], row_3); + assert_eq!(*pad.row_metas[2], row_2); } - fn test_row_meta(id: &str, pad: &GridBlockMetaDataPad) -> RowMeta { + fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { RowMeta { id: id.to_string(), block_id: pad.block_id.clone(), @@ -280,9 +287,9 @@ mod tests { let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); - assert_eq!(*pad.rows[0], row_3); - assert_eq!(*pad.rows[1], row_1); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.row_metas[0], row_3); + assert_eq!(*pad.row_metas[1], row_1); + assert_eq!(*pad.row_metas[2], row_2); } #[test] @@ -296,9 +303,9 @@ mod tests { let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row(row_3.clone(), Some("".to_string())).unwrap().unwrap(); - assert_eq!(*pad.rows[0], row_3); - assert_eq!(*pad.rows[1], row_1); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.row_metas[0], row_3); + assert_eq!(*pad.row_metas[1], row_1); + assert_eq!(*pad.row_metas[2], row_2); } #[test] @@ -317,7 +324,7 @@ mod tests { let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"delete":77},{"retain":2}]"# + r#"[{"retain":29},{"delete":77},{"retain":2}]"# ); assert_eq!(pad.delta_str(), pre_delta_str); @@ -346,17 +353,18 @@ mod tests { assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":80},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# + r#"[{"retain":85},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# ); assert_eq!( pad.to_json().unwrap(), - r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# + r#"{"block_id":"1","row_metas":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# ); } - fn test_pad() -> GridBlockMetaDataPad { - let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - GridBlockMetaDataPad::from_delta(delta).unwrap() + fn test_pad() -> GridBlockMetaPad { + let delta = + GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"row_metas\":[]}"}]"#).unwrap(); + GridBlockMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 3eb8af06c3..2875a8968c 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -13,9 +13,9 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.build_context.grid_block.block_id); - self.build_context.grid_block_meta_data.row_metas.push(row); - self.build_context.grid_block.row_count += 1; + let row = RowMeta::new(&self.build_context.block_metas.block_id); + self.build_context.block_meta_data.row_metas.push(row); + self.build_context.block_metas.row_count += 1; self } @@ -41,7 +41,7 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { mod tests { use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; - use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaSerde, GridMeta}; #[test] fn create_default_grid_test() { @@ -57,13 +57,13 @@ mod tests { let grid_meta = GridMeta { grid_id, fields: build_context.field_metas, - blocks: vec![build_context.grid_block], + block_metas: vec![build_context.block_metas], }; let grid_meta_delta = make_grid_delta(&grid_meta); let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); - let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); + let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data); + let _: GridBlockMetaSerde = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index 31c6ed0fbf..8d4ab37b6d 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -140,12 +140,12 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().any(|b| b.block_id == block.block_id) { + if grid.block_metas.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { - match grid.blocks.last() { - None => grid.blocks.push(block), + match grid.block_metas.last() { + None => grid.block_metas.push(block), Some(last_block) => { if last_block.start_row_index > block.start_row_index && last_block.len() > block.start_row_index @@ -153,7 +153,7 @@ impl GridMetaPad { let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string(); return Err(CollaborateError::internal().context(msg)) } - grid.blocks.push(block); + grid.block_metas.push(block); } } Ok(Some(())) @@ -162,7 +162,7 @@ impl GridMetaPad { } pub fn get_blocks(&self) -> Vec { - self.grid_meta.blocks.clone() + self.grid_meta.block_metas.clone() } pub fn update_block(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { @@ -226,12 +226,12 @@ impl GridMetaPad { F: FnOnce(&mut GridBlockMeta) -> CollaborateResult>, { self.modify_grid( - |grid| match grid.blocks.iter().position(|block| block.block_id == block_id) { + |grid| match grid.block_metas.iter().position(|block| block.block_id == block_id) { None => { tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); Ok(None) } - Some(index) => f(&mut grid.blocks[index]), + Some(index) => f(&mut grid.block_metas[index]), }, ) } @@ -279,7 +279,7 @@ impl std::default::Default for GridMetaPad { let grid = GridMeta { grid_id: uuid(), fields: vec![], - blocks: vec![], + block_metas: vec![], }; let delta = make_grid_delta(&grid); GridMetaPad { diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index f41d3601b4..5df06e7858 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,7 +1,7 @@ -mod grid_block_meta_data_pad; +mod grid_block_meta_pad; mod grid_builder; mod grid_meta_pad; -pub use grid_block_meta_data_pad::*; +pub use grid_block_meta_pad::*; pub use grid_builder::*; pub use grid_meta_pad::*; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index 166202bd5b..e184fd41bf 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -85,8 +85,14 @@ pub enum ErrorCode { UserNotExist = 312, #[display(fmt = "Text is too long")] TextTooLong = 400, + #[display(fmt = "Grid block id is empty")] + BlockIdIsEmpty = 401, + #[display(fmt = "Row id is empty")] + RowIdIsEmpty = 402, + #[display(fmt = "Grid id is empty")] + GridIdIsEmpty = 403, #[display(fmt = "Invalid data")] - InvalidData = 401, + InvalidData = 404, } impl ErrorCode { diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index 769c059eb2..85a0721d7c 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -56,7 +56,10 @@ pub enum ErrorCode { UserIdInvalid = 311, UserNotExist = 312, TextTooLong = 400, - InvalidData = 401, + BlockIdIsEmpty = 401, + RowIdIsEmpty = 402, + GridIdIsEmpty = 403, + InvalidData = 404, } impl ::protobuf::ProtobufEnum for ErrorCode { @@ -97,7 +100,10 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 311 => ::std::option::Option::Some(ErrorCode::UserIdInvalid), 312 => ::std::option::Option::Some(ErrorCode::UserNotExist), 400 => ::std::option::Option::Some(ErrorCode::TextTooLong), - 401 => ::std::option::Option::Some(ErrorCode::InvalidData), + 401 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty), + 402 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), + 403 => ::std::option::Option::Some(ErrorCode::GridIdIsEmpty), + 404 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None } } @@ -135,6 +141,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::UserIdInvalid, ErrorCode::UserNotExist, ErrorCode::TextTooLong, + ErrorCode::BlockIdIsEmpty, + ErrorCode::RowIdIsEmpty, + ErrorCode::GridIdIsEmpty, ErrorCode::InvalidData, ]; values @@ -164,7 +173,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xe8\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xa4\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x18\n\x14WorkspaceNameInvalid\x10d\x12\x16\n\x12WorkspaceIdInvalid\x10e\ \x12\x18\n\x14AppColorStyleInvalid\x10f\x12\x18\n\x14WorkspaceDescTooLon\ @@ -181,8 +190,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\n\"UserNameContainForbiddenCh\ aracters\x10\xb5\x02\x12\x14\n\x0fUserNameIsEmpty\x10\xb6\x02\x12\x12\n\ \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02\x12\ - \x10\n\x0bTextTooLong\x10\x90\x03\x12\x10\n\x0bInvalidData\x10\x91\x03b\ - \x06proto3\ + \x10\n\x0bTextTooLong\x10\x90\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\x91\ + \x03\x12\x11\n\x0cRowIdIsEmpty\x10\x92\x03\x12\x12\n\rGridIdIsEmpty\x10\ + \x93\x03\x12\x10\n\x0bInvalidData\x10\x94\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index 4bf692b8ff..7015c1fe38 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -32,5 +32,8 @@ enum ErrorCode { UserIdInvalid = 311; UserNotExist = 312; TextTooLong = 400; - InvalidData = 401; + BlockIdIsEmpty = 401; + RowIdIsEmpty = 402; + GridIdIsEmpty = 403; + InvalidData = 404; } diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index c0e5bb91bc..89461b444c 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -14,6 +14,7 @@ strum_macros = "0.21" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} uuid = { version = "0.8", features = ["serde", "v4"] } +flowy-error-code = { path = "../flowy-error-code"} [build-dependencies] lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] } diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 95a0454eb1..48aa574298 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,7 +1,9 @@ -use crate::entities::{FieldMeta, FieldType, GridBlockMeta, RowMeta}; +use crate::entities::{FieldMeta, FieldType, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; -use std::hash::Hash; + +use crate::parser::NonEmptyId; +use flowy_error_code::ErrorCode; use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] @@ -13,7 +15,7 @@ pub struct Grid { pub field_orders: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub block_orders: Vec, } #[derive(Debug, Clone, Default, ProtoBuf)] @@ -169,6 +171,18 @@ pub struct Row { pub height: i32, } +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedRow { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::convert::From> for RepeatedRow { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedGridBlock { #[pb(index = 1)] @@ -181,20 +195,26 @@ impl std::convert::From> for RepeatedGridBlock { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct GridBlockOrder { + #[pb(index = 1)] + pub block_id: String, +} + #[derive(Debug, Default, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] pub block_id: String, #[pb(index = 2)] - pub rows: Vec, + pub row_ids: Vec, } impl GridBlock { - pub fn new(block_id: &str, rows: Vec) -> Self { + pub fn new(block_id: &str, row_ids: Vec) -> Self { Self { block_id: block_id.to_owned(), - rows, + row_ids, } } } @@ -278,7 +298,7 @@ pub struct CreateRowPayload { pub grid_id: String, #[pb(index = 2, one_of)] - pub upper_row_id: Option, + pub start_row_id: Option, } #[derive(ProtoBuf, Default)] @@ -296,5 +316,17 @@ pub struct QueryGridBlocksPayload { pub grid_id: String, #[pb(index = 2)] - pub blocks: Vec, + pub block_orders: Vec, +} + +#[derive(ProtoBuf, Default)] +pub struct QueryRowPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub block_id: String, + + #[pb(index = 3)] + pub row_id: String, } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 62a545fcb0..c7c621d7ec 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -2,6 +2,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use crate::entities::GridBlockOrder; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; @@ -16,7 +17,7 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub block_metas: Vec, } #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] @@ -33,7 +34,7 @@ pub struct GridBlockMeta { impl GridBlockMeta { pub fn len(&self) -> i32 { - self.start_row_index + self.row_count + self.row_count } pub fn is_empty(&self) -> bool { @@ -67,7 +68,7 @@ impl GridBlockMetaChangeset { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlockMetaData { +pub struct GridBlockMetaSerde { #[pb(index = 1)] pub block_id: String, @@ -329,24 +330,24 @@ pub struct BuildGridContext { pub field_metas: Vec, #[pb(index = 2)] - pub grid_block: GridBlockMeta, + pub block_metas: GridBlockMeta, #[pb(index = 3)] - pub grid_block_meta_data: GridBlockMetaData, + pub block_meta_data: GridBlockMetaSerde, } impl std::default::Default for BuildGridContext { fn default() -> Self { let grid_block = GridBlockMeta::new(); - let grid_block_meta_data = GridBlockMetaData { + let grid_block_meta_data = GridBlockMetaSerde { block_id: grid_block.block_id.clone(), row_metas: vec![], }; Self { field_metas: vec![], - grid_block, - grid_block_meta_data, + block_metas: grid_block, + block_meta_data: grid_block_meta_data, } } } diff --git a/shared-lib/flowy-grid-data-model/src/lib.rs b/shared-lib/flowy-grid-data-model/src/lib.rs index 85976edd74..bd9ed4465e 100644 --- a/shared-lib/flowy-grid-data-model/src/lib.rs +++ b/shared-lib/flowy-grid-data-model/src/lib.rs @@ -1,2 +1,3 @@ pub mod entities; +pub mod parser; pub mod protobuf; diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid.rs b/shared-lib/flowy-grid-data-model/src/parser/grid.rs new file mode 100644 index 0000000000..49a202cf70 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/grid.rs @@ -0,0 +1,82 @@ +use crate::entities::{ + CreateRowPayload, GridBlockOrder, QueryFieldPayload, QueryGridBlocksPayload, QueryRowPayload, RepeatedFieldOrder, +}; +use crate::parser::NonEmptyId; +use flowy_error_code::ErrorCode; + +#[derive(Default)] +pub struct CreateRowParams { + pub grid_id: String, + pub start_row_id: Option, +} + +impl TryInto for CreateRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(CreateRowParams { + grid_id: grid_id.0, + start_row_id: self.start_row_id, + }) + } +} + +#[derive(Default)] +pub struct QueryFieldParams { + pub grid_id: String, + pub field_orders: RepeatedFieldOrder, +} + +impl TryInto for QueryFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryFieldParams { + grid_id: grid_id.0, + field_orders: self.field_orders, + }) + } +} + +#[derive(Default)] +pub struct QueryGridBlocksParams { + pub grid_id: String, + pub block_orders: Vec, +} + +impl TryInto for QueryGridBlocksPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryGridBlocksParams { + grid_id: grid_id.0, + block_orders: self.block_orders, + }) + } +} + +#[derive(Default)] +pub struct QueryRowParams { + pub grid_id: String, + pub block_id: String, + pub row_id: String, +} + +impl TryInto for QueryRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let block_id = NonEmptyId::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; + let row_id = NonEmptyId::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(QueryRowParams { + grid_id: grid_id.0, + block_id: block_id.0, + row_id: row_id.0, + }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/id.rs b/shared-lib/flowy-grid-data-model/src/parser/id.rs new file mode 100644 index 0000000000..0f35fbfef5 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/id.rs @@ -0,0 +1,20 @@ +use flowy_error_code::ErrorCode; + +#[derive(Debug)] +pub struct NonEmptyId(pub String); + +impl NonEmptyId { + pub fn parse(s: String) -> Result { + if s.trim().is_empty() { + return Err(()); + } + + Ok(Self(s)) + } +} + +impl AsRef for NonEmptyId { + fn as_ref(&self) -> &str { + &self.0 + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/mod.rs b/shared-lib/flowy-grid-data-model/src/parser/mod.rs new file mode 100644 index 0000000000..ec81801043 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/mod.rs @@ -0,0 +1,5 @@ +mod grid; +mod id; + +pub use grid::*; +pub use id::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 6e76d92a7c..630e109891 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -28,7 +28,7 @@ pub struct Grid { // message fields pub id: ::std::string::String, pub field_orders: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub block_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl Grid { ::std::mem::replace(&mut self.field_orders, ::protobuf::RepeatedField::new()) } - // repeated .GridBlockMeta blocks = 3; + // repeated .GridBlockOrder block_orders = 3; - pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { - &self.blocks + pub fn get_block_orders(&self) -> &[GridBlockOrder] { + &self.block_orders } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); + pub fn clear_block_orders(&mut self) { + self.block_orders.clear(); } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; + pub fn set_block_orders(&mut self, v: ::protobuf::RepeatedField) { + self.block_orders = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks + pub fn mut_block_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.block_orders } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) + pub fn take_block_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.block_orders, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for Grid { return false; } }; - for v in &self.blocks { + for v in &self.block_orders { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for Grid { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_orders)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for Grid { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.blocks { + for value in &self.block_orders { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for Grid { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.blocks { + for v in &self.block_orders { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -240,10 +240,10 @@ impl ::protobuf::Message for Grid { |m: &Grid| { &m.field_orders }, |m: &mut Grid| { &mut m.field_orders }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &Grid| { &m.blocks }, - |m: &mut Grid| { &mut m.blocks }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "block_orders", + |m: &Grid| { &m.block_orders }, + |m: &mut Grid| { &mut m.block_orders }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Grid", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for Grid { fn clear(&mut self) { self.id.clear(); self.field_orders.clear(); - self.blocks.clear(); + self.block_orders.clear(); self.unknown_fields.clear(); } } @@ -1748,6 +1748,172 @@ impl ::protobuf::reflect::ProtobufValue for Row { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedRow { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedRow { + fn default() -> &'a RepeatedRow { + ::default_instance() + } +} + +impl RepeatedRow { + pub fn new() -> RepeatedRow { + ::std::default::Default::default() + } + + // repeated .Row items = 1; + + + pub fn get_items(&self) -> &[Row] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedRow { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedRow { + RepeatedRow::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedRow| { &m.items }, + |m: &mut RepeatedRow| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedRow", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedRow { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedRow::new) + } +} + +impl ::protobuf::Clear for RepeatedRow { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedRow { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedRow { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedGridBlock { // message fields @@ -1914,11 +2080,170 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedGridBlock { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockOrder { + // message fields + pub block_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockOrder { + fn default() -> &'a GridBlockOrder { + ::default_instance() + } +} + +impl GridBlockOrder { + pub fn new() -> GridBlockOrder { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for GridBlockOrder { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlockOrder { + GridBlockOrder::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlockOrder| { &m.block_id }, + |m: &mut GridBlockOrder| { &mut m.block_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockOrder::new) + } +} + +impl ::protobuf::Clear for GridBlockOrder { + fn clear(&mut self) { + self.block_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GridBlock { // message fields pub block_id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, + pub row_ids: ::protobuf::RepeatedField<::std::string::String>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1961,39 +2286,34 @@ impl GridBlock { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .Row rows = 2; + // repeated string row_ids = 2; - pub fn get_rows(&self) -> &[Row] { - &self.rows + pub fn get_row_ids(&self) -> &[::std::string::String] { + &self.row_ids } - pub fn clear_rows(&mut self) { - self.rows.clear(); + pub fn clear_row_ids(&mut self) { + self.row_ids.clear(); } // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; + pub fn set_row_ids(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.row_ids = v; } // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows + pub fn mut_row_ids(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.row_ids } // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + pub fn take_row_ids(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.row_ids, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for GridBlock { fn is_initialized(&self) -> bool { - for v in &self.rows { - if !v.is_initialized() { - return false; - } - }; true } @@ -2005,7 +2325,7 @@ impl ::protobuf::Message for GridBlock { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.row_ids)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2022,9 +2342,8 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.rows { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + for value in &self.row_ids { + my_size += ::protobuf::rt::string_size(2, &value); }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2035,10 +2354,8 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.rows { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; + for v in &self.row_ids { + os.write_string(2, &v)?; }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2083,10 +2400,10 @@ impl ::protobuf::Message for GridBlock { |m: &GridBlock| { &m.block_id }, |m: &mut GridBlock| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridBlock| { &m.rows }, - |m: &mut GridBlock| { &mut m.rows }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_ids", + |m: &GridBlock| { &m.row_ids }, + |m: &mut GridBlock| { &mut m.row_ids }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlock", @@ -2105,7 +2422,7 @@ impl ::protobuf::Message for GridBlock { impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { self.block_id.clear(); - self.rows.clear(); + self.row_ids.clear(); self.unknown_fields.clear(); } } @@ -2971,7 +3288,7 @@ pub struct CreateRowPayload { // message fields pub grid_id: ::std::string::String, // message oneof groups - pub one_of_upper_row_id: ::std::option::Option, + pub one_of_start_row_id: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2984,8 +3301,8 @@ impl<'a> ::std::default::Default for &'a CreateRowPayload { } #[derive(Clone,PartialEq,Debug)] -pub enum CreateRowPayload_oneof_one_of_upper_row_id { - upper_row_id(::std::string::String), +pub enum CreateRowPayload_oneof_one_of_start_row_id { + start_row_id(::std::string::String), } impl CreateRowPayload { @@ -3019,48 +3336,48 @@ impl CreateRowPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // string upper_row_id = 2; + // string start_row_id = 2; - pub fn get_upper_row_id(&self) -> &str { - match self.one_of_upper_row_id { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v)) => v, + pub fn get_start_row_id(&self) -> &str { + match self.one_of_start_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref v)) => v, _ => "", } } - pub fn clear_upper_row_id(&mut self) { - self.one_of_upper_row_id = ::std::option::Option::None; + pub fn clear_start_row_id(&mut self) { + self.one_of_start_row_id = ::std::option::Option::None; } - pub fn has_upper_row_id(&self) -> bool { - match self.one_of_upper_row_id { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(..)) => true, + pub fn has_start_row_id(&self) -> bool { + match self.one_of_start_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(..)) => true, _ => false, } } // Param is passed by value, moved - pub fn set_upper_row_id(&mut self, v: ::std::string::String) { - self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) + pub fn set_start_row_id(&mut self, v: ::std::string::String) { + self.one_of_start_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(v)) } // Mutable pointer to the field. - pub fn mut_upper_row_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(_)) = self.one_of_upper_row_id { + pub fn mut_start_row_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(_)) = self.one_of_start_row_id { } else { - self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(::std::string::String::new())); + self.one_of_start_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(::std::string::String::new())); } - match self.one_of_upper_row_id { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref mut v)) => v, + match self.one_of_start_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref mut v)) => v, _ => panic!(), } } // Take field - pub fn take_upper_row_id(&mut self) -> ::std::string::String { - if self.has_upper_row_id() { - match self.one_of_upper_row_id.take() { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) => v, + pub fn take_start_row_id(&mut self) -> ::std::string::String { + if self.has_start_row_id() { + match self.one_of_start_row_id.take() { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(v)) => v, _ => panic!(), } } else { @@ -3085,7 +3402,7 @@ impl ::protobuf::Message for CreateRowPayload { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(is.read_string()?)); + self.one_of_start_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(is.read_string()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3102,9 +3419,9 @@ impl ::protobuf::Message for CreateRowPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + if let ::std::option::Option::Some(ref v) = self.one_of_start_row_id { match v { - &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + &CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref v) => { my_size += ::protobuf::rt::string_size(2, &v); }, }; @@ -3118,9 +3435,9 @@ impl ::protobuf::Message for CreateRowPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + if let ::std::option::Option::Some(ref v) = self.one_of_start_row_id { match v { - &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + &CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref v) => { os.write_string(2, v)?; }, }; @@ -3169,9 +3486,9 @@ impl ::protobuf::Message for CreateRowPayload { |m: &mut CreateRowPayload| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "upper_row_id", - CreateRowPayload::has_upper_row_id, - CreateRowPayload::get_upper_row_id, + "start_row_id", + CreateRowPayload::has_start_row_id, + CreateRowPayload::get_start_row_id, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateRowPayload", @@ -3190,7 +3507,7 @@ impl ::protobuf::Message for CreateRowPayload { impl ::protobuf::Clear for CreateRowPayload { fn clear(&mut self) { self.grid_id.clear(); - self.one_of_upper_row_id = ::std::option::Option::None; + self.one_of_start_row_id = ::std::option::Option::None; self.unknown_fields.clear(); } } @@ -3427,7 +3744,7 @@ impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload { pub struct QueryGridBlocksPayload { // message fields pub grid_id: ::std::string::String, - pub blocks: ::protobuf::RepeatedField, + pub block_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3470,35 +3787,35 @@ impl QueryGridBlocksPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // repeated .GridBlockMeta blocks = 2; + // repeated .GridBlockOrder block_orders = 2; - pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { - &self.blocks + pub fn get_block_orders(&self) -> &[GridBlockOrder] { + &self.block_orders } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); + pub fn clear_block_orders(&mut self) { + self.block_orders.clear(); } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; + pub fn set_block_orders(&mut self, v: ::protobuf::RepeatedField) { + self.block_orders = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks + pub fn mut_block_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.block_orders } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) + pub fn take_block_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.block_orders, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for QueryGridBlocksPayload { fn is_initialized(&self) -> bool { - for v in &self.blocks { + for v in &self.block_orders { if !v.is_initialized() { return false; } @@ -3514,7 +3831,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3531,7 +3848,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - for value in &self.blocks { + for value in &self.block_orders { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -3544,7 +3861,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - for v in &self.blocks { + for v in &self.block_orders { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -3592,10 +3909,10 @@ impl ::protobuf::Message for QueryGridBlocksPayload { |m: &QueryGridBlocksPayload| { &m.grid_id }, |m: &mut QueryGridBlocksPayload| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &QueryGridBlocksPayload| { &m.blocks }, - |m: &mut QueryGridBlocksPayload| { &mut m.blocks }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "block_orders", + |m: &QueryGridBlocksPayload| { &m.block_orders }, + |m: &mut QueryGridBlocksPayload| { &mut m.block_orders }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "QueryGridBlocksPayload", @@ -3614,7 +3931,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { impl ::protobuf::Clear for QueryGridBlocksPayload { fn clear(&mut self) { self.grid_id.clear(); - self.blocks.clear(); + self.block_orders.clear(); self.unknown_fields.clear(); } } @@ -3631,43 +3948,291 @@ impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct QueryRowPayload { + // message fields + pub grid_id: ::std::string::String, + pub block_id: ::std::string::String, + pub row_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a QueryRowPayload { + fn default() -> &'a QueryRowPayload { + ::default_instance() + } +} + +impl QueryRowPayload { + pub fn new() -> QueryRowPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string block_id = 2; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // string row_id = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for QueryRowPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.block_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.block_id.is_empty() { + os.write_string(2, &self.block_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> QueryRowPayload { + QueryRowPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &QueryRowPayload| { &m.grid_id }, + |m: &mut QueryRowPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &QueryRowPayload| { &m.block_id }, + |m: &mut QueryRowPayload| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &QueryRowPayload| { &m.row_id }, + |m: &mut QueryRowPayload| { &mut m.row_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryRowPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static QueryRowPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryRowPayload::new) + } +} + +impl ::protobuf::Clear for QueryRowPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.block_id.clear(); + self.row_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for QueryRowPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\x1a\nmeta.proto\"n\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ + \n\ngrid.proto\x1a\nmeta.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ - erR\x0bfieldOrders\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockM\ - etaR\x06blocks\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ - \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ - FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ - n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ - id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ - \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"<\n\x08\ - RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ - lock_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10RepeatedRowOrder\x12\x1f\ - \n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Ro\ - w\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\ - \x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\ - \x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldId\ - Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ - \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"5\n\x11RepeatedGridBloc\ - k\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"@\n\tG\ - ridBlock\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x18\n\ - \x04rows\x18\x02\x20\x03(\x0b2\x04.RowR\x04rows\";\n\x04Cell\x12\x19\n\ - \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ - \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ - \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ - \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ - e\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ - \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ - _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\x02\x20\ - \x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryField\ - Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ - ld_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\ - Y\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12&\n\x06blocks\x18\x02\x20\x03(\x0b2\x0e.GridBlockMetaR\x06\ - blocksb\x06proto3\ + erR\x0bfieldOrders\x122\n\x0cblock_orders\x18\x03\x20\x03(\x0b2\x0f.Grid\ + BlockOrderR\x0bblockOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\ + \n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\ + \x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\ + \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ + \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\ + \x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Re\ + peatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\ + \x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ + wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10Repeate\ + dRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\ + \"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10\ + cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcell\ + ByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12\ + CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\ + \x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRep\ + eatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\ + \x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlo\ + ckR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\x08block_id\x18\x01\x20\ + \x01(\tR\x07blockId\"?\n\tGridBlock\x12\x19\n\x08block_id\x18\x01\x20\ + \x01(\tR\x07blockId\x12\x17\n\x07row_ids\x18\x02\x20\x03(\tR\x06rowIds\"\ + ;\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\ + \n\x07content\x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\ + \x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateG\ + ridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06Grid\ + Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\ + \x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayloa\ + d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_ro\ + w_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"d\ + \n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ + Id\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ + \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ + \x0f.GridBlockOrderR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ + \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ + b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 0dcde28a6b..2e27686c00 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub block_metas: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .GridBlockMeta blocks = 3; + // repeated .GridBlockMeta block_metas = 3; - pub fn get_blocks(&self) -> &[GridBlockMeta] { - &self.blocks + pub fn get_block_metas(&self) -> &[GridBlockMeta] { + &self.block_metas } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); + pub fn clear_block_metas(&mut self) { + self.block_metas.clear(); } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; + pub fn set_block_metas(&mut self, v: ::protobuf::RepeatedField) { + self.block_metas = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks + pub fn mut_block_metas(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.block_metas } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) + pub fn take_block_metas(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.block_metas, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta { return false; } }; - for v in &self.blocks { + for v in &self.block_metas { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_metas)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.blocks { + for value in &self.block_metas { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.blocks { + for v in &self.block_metas { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -241,9 +241,9 @@ impl ::protobuf::Message for GridMeta { |m: &mut GridMeta| { &mut m.fields }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &GridMeta| { &m.blocks }, - |m: &mut GridMeta| { &mut m.blocks }, + "block_metas", + |m: &GridMeta| { &m.block_metas }, + |m: &mut GridMeta| { &mut m.block_metas }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridMeta", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta { fn clear(&mut self) { self.grid_id.clear(); self.fields.clear(); - self.blocks.clear(); + self.block_metas.clear(); self.unknown_fields.clear(); } } @@ -510,7 +510,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } #[derive(PartialEq,Clone,Default)] -pub struct GridBlockMetaData { +pub struct GridBlockMetaSerde { // message fields pub block_id: ::std::string::String, pub row_metas: ::protobuf::RepeatedField, @@ -519,14 +519,14 @@ pub struct GridBlockMetaData { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridBlockMetaData { - fn default() -> &'a GridBlockMetaData { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlockMetaSerde { + fn default() -> &'a GridBlockMetaSerde { + ::default_instance() } } -impl GridBlockMetaData { - pub fn new() -> GridBlockMetaData { +impl GridBlockMetaSerde { + pub fn new() -> GridBlockMetaSerde { ::std::default::Default::default() } @@ -582,7 +582,7 @@ impl GridBlockMetaData { } } -impl ::protobuf::Message for GridBlockMetaData { +impl ::protobuf::Message for GridBlockMetaSerde { fn is_initialized(&self) -> bool { for v in &self.row_metas { if !v.is_initialized() { @@ -665,8 +665,8 @@ impl ::protobuf::Message for GridBlockMetaData { Self::descriptor_static() } - fn new() -> GridBlockMetaData { - GridBlockMetaData::new() + fn new() -> GridBlockMetaSerde { + GridBlockMetaSerde::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -675,29 +675,29 @@ impl ::protobuf::Message for GridBlockMetaData { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &GridBlockMetaData| { &m.block_id }, - |m: &mut GridBlockMetaData| { &mut m.block_id }, + |m: &GridBlockMetaSerde| { &m.block_id }, + |m: &mut GridBlockMetaSerde| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "row_metas", - |m: &GridBlockMetaData| { &m.row_metas }, - |m: &mut GridBlockMetaData| { &mut m.row_metas }, + |m: &GridBlockMetaSerde| { &m.row_metas }, + |m: &mut GridBlockMetaSerde| { &mut m.row_metas }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlockMetaData", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMetaSerde", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridBlockMetaData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlockMetaData::new) + fn default_instance() -> &'static GridBlockMetaSerde { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMetaSerde::new) } } -impl ::protobuf::Clear for GridBlockMetaData { +impl ::protobuf::Clear for GridBlockMetaSerde { fn clear(&mut self) { self.block_id.clear(); self.row_metas.clear(); @@ -705,13 +705,13 @@ impl ::protobuf::Clear for GridBlockMetaData { } } -impl ::std::fmt::Debug for GridBlockMetaData { +impl ::std::fmt::Debug for GridBlockMetaSerde { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData { +impl ::protobuf::reflect::ProtobufValue for GridBlockMetaSerde { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3119,8 +3119,8 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { pub struct BuildGridContext { // message fields pub field_metas: ::protobuf::RepeatedField, - pub grid_block: ::protobuf::SingularPtrField, - pub grid_block_meta_data: ::protobuf::SingularPtrField, + pub block_metas: ::protobuf::SingularPtrField, + pub block_meta_data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3162,70 +3162,70 @@ impl BuildGridContext { ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) } - // .GridBlockMeta grid_block = 2; + // .GridBlockMeta block_metas = 2; - pub fn get_grid_block(&self) -> &GridBlockMeta { - self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_block_metas(&self) -> &GridBlockMeta { + self.block_metas.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_grid_block(&mut self) { - self.grid_block.clear(); + pub fn clear_block_metas(&mut self) { + self.block_metas.clear(); } - pub fn has_grid_block(&self) -> bool { - self.grid_block.is_some() + pub fn has_block_metas(&self) -> bool { + self.block_metas.is_some() } // Param is passed by value, moved - pub fn set_grid_block(&mut self, v: GridBlockMeta) { - self.grid_block = ::protobuf::SingularPtrField::some(v); + pub fn set_block_metas(&mut self, v: GridBlockMeta) { + self.block_metas = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block(&mut self) -> &mut GridBlockMeta { - if self.grid_block.is_none() { - self.grid_block.set_default(); + pub fn mut_block_metas(&mut self) -> &mut GridBlockMeta { + if self.block_metas.is_none() { + self.block_metas.set_default(); } - self.grid_block.as_mut().unwrap() + self.block_metas.as_mut().unwrap() } // Take field - pub fn take_grid_block(&mut self) -> GridBlockMeta { - self.grid_block.take().unwrap_or_else(|| GridBlockMeta::new()) + pub fn take_block_metas(&mut self) -> GridBlockMeta { + self.block_metas.take().unwrap_or_else(|| GridBlockMeta::new()) } - // .GridBlockMetaData grid_block_meta_data = 3; + // .GridBlockMetaSerde block_meta_data = 3; - pub fn get_grid_block_meta_data(&self) -> &GridBlockMetaData { - self.grid_block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_block_meta_data(&self) -> &GridBlockMetaSerde { + self.block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_grid_block_meta_data(&mut self) { - self.grid_block_meta_data.clear(); + pub fn clear_block_meta_data(&mut self) { + self.block_meta_data.clear(); } - pub fn has_grid_block_meta_data(&self) -> bool { - self.grid_block_meta_data.is_some() + pub fn has_block_meta_data(&self) -> bool { + self.block_meta_data.is_some() } // Param is passed by value, moved - pub fn set_grid_block_meta_data(&mut self, v: GridBlockMetaData) { - self.grid_block_meta_data = ::protobuf::SingularPtrField::some(v); + pub fn set_block_meta_data(&mut self, v: GridBlockMetaSerde) { + self.block_meta_data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block_meta_data(&mut self) -> &mut GridBlockMetaData { - if self.grid_block_meta_data.is_none() { - self.grid_block_meta_data.set_default(); + pub fn mut_block_meta_data(&mut self) -> &mut GridBlockMetaSerde { + if self.block_meta_data.is_none() { + self.block_meta_data.set_default(); } - self.grid_block_meta_data.as_mut().unwrap() + self.block_meta_data.as_mut().unwrap() } // Take field - pub fn take_grid_block_meta_data(&mut self) -> GridBlockMetaData { - self.grid_block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new()) + pub fn take_block_meta_data(&mut self) -> GridBlockMetaSerde { + self.block_meta_data.take().unwrap_or_else(|| GridBlockMetaSerde::new()) } } @@ -3236,12 +3236,12 @@ impl ::protobuf::Message for BuildGridContext { return false; } }; - for v in &self.grid_block { + for v in &self.block_metas { if !v.is_initialized() { return false; } }; - for v in &self.grid_block_meta_data { + for v in &self.block_meta_data { if !v.is_initialized() { return false; } @@ -3257,10 +3257,10 @@ impl ::protobuf::Message for BuildGridContext { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_metas)?; }, 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta_data)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta_data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3278,11 +3278,11 @@ impl ::protobuf::Message for BuildGridContext { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - if let Some(ref v) = self.grid_block.as_ref() { + if let Some(ref v) = self.block_metas.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if let Some(ref v) = self.grid_block_meta_data.as_ref() { + if let Some(ref v) = self.block_meta_data.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -3297,12 +3297,12 @@ impl ::protobuf::Message for BuildGridContext { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - if let Some(ref v) = self.grid_block.as_ref() { + if let Some(ref v) = self.block_metas.as_ref() { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - if let Some(ref v) = self.grid_block_meta_data.as_ref() { + if let Some(ref v) = self.block_meta_data.as_ref() { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -3351,14 +3351,14 @@ impl ::protobuf::Message for BuildGridContext { |m: &mut BuildGridContext| { &mut m.field_metas }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "grid_block", - |m: &BuildGridContext| { &m.grid_block }, - |m: &mut BuildGridContext| { &mut m.grid_block }, + "block_metas", + |m: &BuildGridContext| { &m.block_metas }, + |m: &mut BuildGridContext| { &mut m.block_metas }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "grid_block_meta_data", - |m: &BuildGridContext| { &m.grid_block_meta_data }, - |m: &mut BuildGridContext| { &mut m.grid_block_meta_data }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "block_meta_data", + |m: &BuildGridContext| { &m.block_meta_data }, + |m: &mut BuildGridContext| { &mut m.block_meta_data }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "BuildGridContext", @@ -3377,8 +3377,8 @@ impl ::protobuf::Message for BuildGridContext { impl ::protobuf::Clear for BuildGridContext { fn clear(&mut self) { self.field_metas.clear(); - self.grid_block.clear(); - self.grid_block_meta_data.clear(); + self.block_metas.clear(); + self.block_meta_data.clear(); self.unknown_fields.clear(); } } @@ -3458,22 +3458,22 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"x\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ - s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\ - \n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ - \x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\ - \n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMetaDat\ - a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_metas\ - \x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldMeta\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\ - \x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nf\ - ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06fro\ - zen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\ - \x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\ - \x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\n\ - \x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\ - \x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ + s\x12/\n\x0bblock_metas\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\nblockM\ + etas\"o\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\ + ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ + \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\ + aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\ + metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldM\ + eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ + \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ + \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ + \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ + \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ + idth\x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\ + \n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldI\ + d\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ \x03\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\ \x03R\x06frozen\x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibi\ @@ -3501,14 +3501,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ \x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\ - \x04dataB\r\n\x0bone_of_data\"\xb3\x01\n\x10BuildGridContext\x12+\n\x0bf\ - ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ngrid_b\ - lock\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tgridBlock\x12C\n\x14grid_\ - block_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\x11gridBloc\ - kMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ - \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ - \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ - o3\ + \x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bf\ + ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bbloc\ + k_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fb\ + lock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaD\ + ata*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\ + \x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\ + \n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 31119b015d..2e85b13411 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -4,7 +4,7 @@ import "meta.proto"; message Grid { string id = 1; repeated FieldOrder field_orders = 2; - repeated GridBlockMeta blocks = 3; + repeated GridBlockOrder block_orders = 3; } message Field { string id = 1; @@ -36,12 +36,18 @@ message Row { map cell_by_field_id = 2; int32 height = 3; } +message RepeatedRow { + repeated Row items = 1; +} message RepeatedGridBlock { repeated GridBlock items = 1; } +message GridBlockOrder { + string block_id = 1; +} message GridBlock { string block_id = 1; - repeated Row rows = 2; + repeated string row_ids = 2; } message Cell { string field_id = 1; @@ -61,7 +67,7 @@ message GridBlockId { } message CreateRowPayload { string grid_id = 1; - oneof one_of_upper_row_id { string upper_row_id = 2; }; + oneof one_of_start_row_id { string start_row_id = 2; }; } message QueryFieldPayload { string grid_id = 1; @@ -69,5 +75,10 @@ message QueryFieldPayload { } message QueryGridBlocksPayload { string grid_id = 1; - repeated GridBlockMeta blocks = 2; + repeated GridBlockOrder block_orders = 2; +} +message QueryRowPayload { + string grid_id = 1; + string block_id = 2; + string row_id = 3; } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index aa23f08a02..24e1d22696 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,14 +3,14 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated FieldMeta fields = 2; - repeated GridBlockMeta blocks = 3; + repeated GridBlockMeta block_metas = 3; } message GridBlockMeta { string block_id = 1; int32 start_row_index = 2; int32 row_count = 3; } -message GridBlockMetaData { +message GridBlockMetaSerde { string block_id = 1; repeated RowMeta row_metas = 2; } @@ -63,8 +63,8 @@ message CellMetaChangeset { } message BuildGridContext { repeated FieldMeta field_metas = 1; - GridBlockMeta grid_block = 2; - GridBlockMetaData grid_block_meta_data = 3; + GridBlockMeta block_metas = 2; + GridBlockMetaSerde block_meta_data = 3; } enum FieldType { RichText = 0; diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 0847950b98..15367cc5ac 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -7,7 +7,7 @@ fn grid_serde_test() { let grid = GridMeta { grid_id, fields, - blocks: vec![], + block_metas: vec![], }; let grid_1_json = serde_json::to_string(&grid).unwrap(); @@ -24,7 +24,7 @@ fn grid_default_serde_test() { let grid = GridMeta { grid_id, fields: vec![], - blocks: vec![], + block_metas: vec![], }; let json = serde_json::to_string(&grid).unwrap(); From 318d7e645640e4fa75cd5bbc9292757867bf9da6 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 18 Mar 2022 21:04:01 +0800 Subject: [PATCH 049/179] chore: fix warnings --- .../application/grid/grid_block_service.dart | 9 +- .../application/grid/grid_service.dart | 3 + .../workspace/application/grid/row_bloc.dart | 32 +- .../application/grid/row_service.dart | 2 + .../presentation/plugins/grid/grid.dart | 2 +- .../src/widgets/content/cell_builder.dart | 1 - .../grid/src/widgets/content/grid_row.dart | 25 +- .../flowy-grid-data-model/grid.pb.dart | 63 +--- .../flowy-grid-data-model/grid.pbjson.dart | 17 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- .../src/services/block_meta_editor.rs | 30 +- .../flowy-grid/src/services/grid_editor.rs | 30 +- .../src/services/row/row_builder.rs | 35 +- .../flowy-grid/src/services/row/row_loader.rs | 22 +- .../rust-lib/flowy-grid/src/services/util.rs | 33 -- .../flowy-grid/tests/grid/grid_test.rs | 16 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 25 +- .../src/entities/grid.rs | 39 +-- .../src/entities/meta.rs | 2 - .../flowy-grid-data-model/src/parser/id.rs | 2 - .../src/protobuf/model/grid.rs | 310 ++++++------------ .../src/protobuf/proto/grid.proto | 6 +- 23 files changed, 253 insertions(+), 457 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 973f412e9e..3672a910f4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -37,13 +37,14 @@ class GridBlockService { List rows() { List rows = []; - blockMap.forEach((_, gridBlock) { - rows.addAll(gridBlock.rowIds.map( - (rowId) => GridRowData( + blockMap.forEach((_, GridBlock gridBlock) { + rows.addAll(gridBlock.rowOrders.map( + (rowOrder) => GridRowData( gridId: gridId, fields: fields, blockId: gridBlock.blockId, - rowId: rowId, + rowId: rowOrder.rowId, + height: rowOrder.height.toDouble(), ), )); }); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 976860029e..506401706b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -40,11 +40,14 @@ class GridRowData extends Equatable { final String rowId; final String blockId; final List fields; + final double height; + const GridRowData({ required this.gridId, required this.rowId, required this.blockId, required this.fields, + required this.height, }); @override diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 32525a1bb7..bf13c682d7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -61,20 +62,29 @@ class RowBloc extends Bloc { final result = await rowService.getRow(); result.fold( (row) { - final cellDatas = rowService.rowData.fields.map((field) { - final cell = row.cellByFieldId[field.id]; - return GridCellData( - rowId: row.id, - gridId: rowService.rowData.gridId, - cell: cell, - field: field, - ); - }).toList(); - emit(state.copyWith(cellDatas: cellDatas, rowHeight: row.height.toDouble())); + emit(state.copyWith( + cellDatas: makeGridCellDatas(row), + rowHeight: row.height.toDouble(), + )); }, (e) => Log.error(e), ); } + + List makeGridCellDatas(Row row) { + return rowService.rowData.fields.map((field) { + final cell = row.cellByFieldId[field.id]; + final rowData = rowService.rowData; + + return GridCellData( + rowId: row.id, + gridId: rowData.gridId, + blockId: rowData.blockId, + cell: cell, + field: field, + ); + }).toList(); + } } @freezed @@ -97,7 +107,7 @@ abstract class RowState with _$RowState { factory RowState.initial(GridRowData data) => RowState( rowId: data.rowId, active: false, - rowHeight: 0, + rowHeight: data.height, cellDatas: [], ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart index 986442c47e..013ae3fb1c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -31,12 +31,14 @@ class RowService { class GridCellData { final String gridId; final String rowId; + final String blockId; final Field field; final Cell? cell; GridCellData({ required this.rowId, required this.gridId, + required this.blockId, required this.field, required this.cell, }); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart index b73970508c..cf6b4c9032 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => true; + bool get creatable => false; } class GridPlugin extends Plugin { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 2bb1782f13..187a81c1bc 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,3 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 45f5f89c38..f062202744 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -36,16 +36,21 @@ class _GridRowWidgetState extends State { cursor: SystemMouseCursors.click, onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - child: SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const LeadingRow(), - _buildCells(), - const TrailingRow(), - ], - ), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingRow(), + _buildCells(), + const TrailingRow(), + ], + ), + ); + }, ), ), ), diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index b44a3e7814..bc713bbdb8 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -338,6 +338,7 @@ class RowOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -345,6 +346,7 @@ class RowOrder extends $pb.GeneratedMessage { factory RowOrder({ $core.String? rowId, $core.String? blockId, + $core.int? height, }) { final _result = create(); if (rowId != null) { @@ -353,6 +355,9 @@ class RowOrder extends $pb.GeneratedMessage { if (blockId != null) { _result.blockId = blockId; } + if (height != null) { + _result.height = height; + } return _result; } factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -393,47 +398,15 @@ class RowOrder extends $pb.GeneratedMessage { $core.bool hasBlockId() => $_has(1); @$pb.TagNumber(2) void clearBlockId() => clearField(2); -} -class RepeatedRowOrder extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRowOrder', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: RowOrder.create) - ..hasRequiredFields = false - ; - - RepeatedRowOrder._() : super(); - factory RepeatedRowOrder({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedRowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedRowOrder.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedRowOrder clone() => RepeatedRowOrder()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedRowOrder copyWith(void Function(RepeatedRowOrder) updates) => super.copyWith((message) => updates(message as RepeatedRowOrder)) as RepeatedRowOrder; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedRowOrder create() => RepeatedRowOrder._(); - RepeatedRowOrder createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedRowOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedRowOrder? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); + @$pb.TagNumber(3) + $core.int get height => $_getIZ(2); + @$pb.TagNumber(3) + set height($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasHeight() => $_has(2); + @$pb.TagNumber(3) + void clearHeight() => clearField(3); } class Row extends $pb.GeneratedMessage { @@ -637,21 +610,21 @@ class GridBlockOrder extends $pb.GeneratedMessage { class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowIds') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false ; GridBlock._() : super(); factory GridBlock({ $core.String? blockId, - $core.Iterable<$core.String>? rowIds, + $core.Iterable? rowOrders, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rowIds != null) { - _result.rowIds.addAll(rowIds); + if (rowOrders != null) { + _result.rowOrders.addAll(rowOrders); } return _result; } @@ -686,7 +659,7 @@ class GridBlock extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List<$core.String> get rowIds => $_getList(1); + $core.List get rowOrders => $_getList(1); } class Cell extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index c4d79ccb0b..5e24c82178 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -72,21 +72,12 @@ const RowOrder$json = const { '2': const [ const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'height', '3': 3, '4': 1, '5': 5, '10': 'height'}, ], }; /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lk'); -@$core.Deprecated('Use repeatedRowOrderDescriptor instead') -const RepeatedRowOrder$json = const { - '1': 'RepeatedRowOrder', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.RowOrder', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z'); +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0'); @$core.Deprecated('Use rowDescriptor instead') const Row$json = const { '1': 'Row', @@ -145,12 +136,12 @@ const GridBlock$json = const { '1': 'GridBlock', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'row_ids', '3': 2, '4': 3, '5': 9, '10': 'rowIds'}, + const {'1': 'row_orders', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSFwoHcm93X2lkcxgCIAMoCVIGcm93SWRz'); +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSKAoKcm93X29yZGVycxgCIAMoCzIJLlJvd09yZGVyUglyb3dPcmRlcnM='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index d6022769fb..73aed6da43 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -2,7 +2,7 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, - QueryRowPayload, RepeatedField, RepeatedGridBlock, RepeatedRow, Row, + QueryRowPayload, RepeatedField, RepeatedGridBlock, Row, }; use flowy_grid_data_model::parser::{CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index f8ba93b906..650b537221 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -9,8 +9,7 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, - RowMetaChangeset, RowOrder, + FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -92,16 +91,7 @@ impl GridBlockMetaEditorManager { Ok(changesets) } - pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { - let row_orders = row_ids - .into_iter() - .flat_map(|row_id| { - self.block_id_by_row_id.get(&row_id).map(|block_id| RowOrder { - row_id, - block_id: block_id.clone(), - }) - }) - .collect::>(); + pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { let mut changesets = vec![]; let row_ids_per_blocks = make_row_ids_per_block(&row_orders); for row_ids_per_block in row_ids_per_blocks { @@ -163,7 +153,7 @@ impl GridBlockMetaEditorManager { pub(crate) async fn get_block_meta_data(&self, block_ids: &[String]) -> FlowyResult> { let mut snapshots = vec![]; for block_id in block_ids { - let editor = self.get_editor(&block_id).await?; + let editor = self.get_editor(block_id).await?; let row_metas = editor.get_row_metas(None).await?; row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id @@ -177,16 +167,6 @@ impl GridBlockMetaEditorManager { Ok(snapshots) } - pub(crate) async fn get_row_orders(&self, grid_block_ids: Vec) -> FlowyResult> { - let mut row_orders = vec![]; - for grid_block_id in grid_block_ids { - let editor = self.get_editor(&grid_block_id).await?; - let new_row_order = editor.get_row_orders().await?; - row_orders.extend(new_row_order); - } - Ok(row_orders) - } - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { match self.block_id_by_row_id.get(row_id) { None => { @@ -328,12 +308,12 @@ impl ClientGridBlockMetaEditor { Ok(row_metas) } - pub async fn get_row_orders(&self) -> FlowyResult> { + pub async fn get_row_orders(&self, row_ids: Option>) -> FlowyResult> { let row_orders = self .pad .read() .await - .get_rows(None)? + .get_rows(row_ids)? .iter() .map(RowOrder::from) .collect::>(); diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 8f4d82d992..d1276bb8ab 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -6,16 +6,15 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, - GridBlockOrder, RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, - RowMetaChangeset, + CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, + RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, Row, RowMeta, RowMetaChangeset, RowOrder, }; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ - make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, make_rows_from_row_metas, - row_meta_from_context, serialize_cell_data, GridBlockMetaData, RowMetaContext, RowMetaContextBuilder, + make_grid_block_from_block_metas, make_grid_blocks, make_row_meta_from_context, make_rows_from_row_metas, + serialize_cell_data, CreateRowMetaBuilder, CreateRowMetaPayload, GridBlockMetaData, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -85,13 +84,14 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_row(&self, start_row_id: Option) -> FlowyResult<()> { + pub async fn create_row(&self, start_row_id: Option) -> FlowyResult { let field_metas = self.pad.read().await.get_field_metas(None)?; let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id - let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build(); - let row_meta = row_meta_from_context(&block_id, row_meta_ctx); + let row_meta_ctx = CreateRowMetaBuilder::new(&field_metas).build(); + let row_meta = make_row_meta_from_context(&block_id, row_meta_ctx); + let row_order = RowOrder::from(&row_meta); // insert the row let row_count = self @@ -102,14 +102,16 @@ impl ClientGridEditor { // update block row count let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; - Ok(()) + Ok(row_order) } - pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult> { let block_id = self.block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); + let mut row_orders = vec![]; for ctx in contexts { - let row_meta = row_meta_from_context(&block_id, ctx); + let row_meta = make_row_meta_from_context(&block_id, ctx); + row_orders.push(RowOrder::from(&row_meta)); rows_by_block_id .entry(block_id.clone()) .or_insert_with(Vec::new) @@ -119,7 +121,7 @@ impl ClientGridEditor { for changeset in changesets { let _ = self.update_block(changeset).await?; } - Ok(()) + Ok(row_orders) } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { @@ -188,8 +190,8 @@ impl ClientGridEditor { Ok(grid_blocks) } - pub async fn delete_rows(&self, row_ids: Vec) -> FlowyResult<()> { - let changesets = self.block_meta_manager.delete_rows(row_ids).await?; + pub async fn delete_rows(&self, row_orders: Vec) -> FlowyResult<()> { + let changesets = self.block_meta_manager.delete_rows(row_orders).await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index ce8ac6e53d..cbaae78fed 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -3,26 +3,29 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; -pub struct RowMetaContextBuilder<'a> { +pub struct CreateRowMetaBuilder<'a> { field_meta_map: HashMap<&'a String, &'a FieldMeta>, - ctx: RowMetaContext, + payload: CreateRowMetaPayload, } -impl<'a> RowMetaContextBuilder<'a> { +impl<'a> CreateRowMetaBuilder<'a> { pub fn new(fields: &'a [FieldMeta]) -> Self { let field_meta_map = fields .iter() .map(|field| (&field.id, field)) .collect::>(); - let ctx = RowMetaContext { + let payload = CreateRowMetaPayload { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, }; - Self { field_meta_map, ctx } + Self { + field_meta_map, + payload, + } } pub fn add_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> { @@ -34,7 +37,7 @@ impl<'a> RowMetaContextBuilder<'a> { Some(field_meta) => { let data = serialize_cell_data(&data, field_meta)?; let cell = CellMeta::new(field_id, data); - self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); + self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); Ok(()) } } @@ -42,32 +45,32 @@ impl<'a> RowMetaContextBuilder<'a> { #[allow(dead_code)] pub fn height(mut self, height: i32) -> Self { - self.ctx.height = height; + self.payload.height = height; self } #[allow(dead_code)] pub fn visibility(mut self, visibility: bool) -> Self { - self.ctx.visibility = visibility; + self.payload.visibility = visibility; self } - pub fn build(self) -> RowMetaContext { - self.ctx + pub fn build(self) -> CreateRowMetaPayload { + self.payload } } -pub fn row_meta_from_context(block_id: &str, ctx: RowMetaContext) -> RowMeta { +pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload) -> RowMeta { RowMeta { - id: ctx.row_id, + id: payload.row_id, block_id: block_id.to_owned(), - cell_by_field_id: ctx.cell_by_field_id, - height: ctx.height, - visibility: ctx.visibility, + cell_by_field_id: payload.cell_by_field_id, + height: payload.height, + visibility: payload.visibility, } } -pub struct RowMetaContext { +pub struct CreateRowMetaPayload { pub row_id: String, pub cell_by_field_id: HashMap, pub height: i32, diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 8d1e683a6e..bf2f62c776 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,7 +1,7 @@ use crate::services::row::deserialize_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, + Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, Row, RowMeta, RowOrder, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; @@ -32,8 +32,8 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec) -> Ok(block_meta_snapshots .into_iter() .map(|row_metas_per_block| { - let row_ids = make_row_ids_from_row_metas(&row_metas_per_block.row_metas); + let row_orders = make_row_orders_from_row_metas(&row_metas_per_block.row_metas); GridBlock { block_id: row_metas_per_block.block_id, - row_ids, + row_orders, } }) .collect::>() @@ -73,11 +73,11 @@ pub fn make_cell( } } -pub(crate) fn make_row_ids_from_row_metas(row_metas: &Vec>) -> Vec { - row_metas.iter().map(|row_meta| row_meta.id.clone()).collect::>() +pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec { + row_metas.iter().map(RowOrder::from).collect::>() } -pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>) -> Vec { +pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc]) -> Vec { let field_meta_map = fields .iter() .map(|field_meta| (&field_meta.id, field_meta)) @@ -98,7 +98,7 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>() + row_metas.iter().map(make_row).collect::>() } pub(crate) fn make_grid_block_from_block_metas( @@ -115,8 +115,8 @@ pub(crate) fn make_grid_block_from_block_metas( match block_meta_data_map.get(&block_id) { None => {} Some(row_metas) => { - let row_ids = make_row_ids_from_row_metas(row_metas); - grid_blocks.push(GridBlock::new(block_id, row_ids)); + let row_orders = make_row_orders_from_row_metas(row_metas); + grid_blocks.push(GridBlock::new(block_id, row_orders)); } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index b5c838fa12..7370a1b19c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,36 +1,3 @@ -// -// #[allow(dead_code)] -// pub fn string_to_money(money_str: &str) -> Option> { -// let mut process_money_str = String::from(money_str); -// let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); -// -// if process_money_str.is_empty() { -// return None; -// } -// -// return if process_money_str.chars().all(char::is_numeric) { -// match Money::from_str(&process_money_str, default_currency) { -// Ok(money) => Some(money), -// Err(_) => None, -// } -// } else { -// let symbol = process_money_str.chars().next().unwrap().to_string(); -// let mut currency = default_currency; -// -// for key in CURRENCIES_BY_SYMBOL.keys() { -// if symbol.eq(key) { -// currency = CURRENCIES_BY_SYMBOL.get(key).unwrap(); -// crop_letters(&mut process_money_str, 1); -// } -// } -// -// match Money::from_str(&process_money_str, currency) { -// Ok(money) => Some(money), -// Err(_) => None, -// } -// }; -// } - pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index dcc077be35..abc00d5fb2 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -2,7 +2,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use chrono::NaiveDateTime; use flowy_grid::services::cell::*; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, RowMetaContextBuilder}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, }; @@ -179,7 +179,7 @@ async fn grid_create_row() { #[tokio::test] async fn grid_create_row2() { let mut test = GridEditorTest::new().await; - let create_row_context = RowMetaContextBuilder::new(&test.field_metas).build(); + let create_row_context = CreateRowMetaBuilder::new(&test.field_metas).build(); let scripts = vec![ AssertRowCount(3), CreateRow { @@ -193,7 +193,7 @@ async fn grid_create_row2() { #[tokio::test] async fn grid_update_row() { let mut test = GridEditorTest::new().await; - let context = RowMetaContextBuilder::new(&test.field_metas).build(); + let context = CreateRowMetaBuilder::new(&test.field_metas).build(); let changeset = RowMetaChangeset { row_id: context.row_id.clone(), height: None, @@ -216,8 +216,8 @@ async fn grid_update_row() { #[tokio::test] async fn grid_delete_row() { let mut test = GridEditorTest::new().await; - let context_1 = RowMetaContextBuilder::new(&test.field_metas).build(); - let context_2 = RowMetaContextBuilder::new(&test.field_metas).build(); + let context_1 = CreateRowMetaBuilder::new(&test.field_metas).build(); + let context_2 = CreateRowMetaBuilder::new(&test.field_metas).build(); let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let scripts = vec![ AssertRowCount(3), @@ -242,7 +242,7 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_row_add_cells_test() { let mut test = GridEditorTest::new().await; - let mut builder = RowMetaContextBuilder::new(&test.field_metas); + let mut builder = CreateRowMetaBuilder::new(&test.field_metas); for field in &test.field_metas { match field.field_type { FieldType::RichText => { @@ -288,7 +288,7 @@ async fn grid_row_add_cells_test() { #[tokio::test] async fn grid_row_add_selection_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = RowMetaContextBuilder::new(&test.field_metas); + let mut builder = CreateRowMetaBuilder::new(&test.field_metas); let uuid = uuid::Uuid::new_v4().to_string(); let mut single_select_field_id = "".to_string(); let mut multi_select_field_id = "".to_string(); @@ -343,7 +343,7 @@ async fn grid_row_add_selection_cell_test() { #[tokio::test] async fn grid_row_add_date_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = RowMetaContextBuilder::new(&test.field_metas); + let mut builder = CreateRowMetaBuilder::new(&test.field_metas); let mut date_field = None; let timestamp = 1647390674; for field in &test.field_metas { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 571ca1ab95..eba36d8bbd 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,13 +1,14 @@ use bytes::Bytes; use flowy_collaboration::client_grid::GridBuilder; +use std::collections::HashMap; use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid::services::row::RowMetaContext; +use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, - RowMeta, RowMetaChangeset, + RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -50,7 +51,7 @@ pub enum EditorScript { }, CreateEmptyRow, CreateRow { - context: RowMetaContext, + context: CreateRowMetaPayload, }, UpdateRow { changeset: RowMetaChangeset, @@ -78,6 +79,8 @@ pub struct GridEditorTest { pub grid_blocks: Vec, pub row_metas: Vec>, pub field_count: usize, + + pub row_order_by_row_id: HashMap, } impl GridEditorTest { @@ -101,6 +104,7 @@ impl GridEditorTest { grid_blocks, row_metas, field_count: FieldType::COUNT, + row_order_by_row_id: HashMap::default(), } } @@ -172,18 +176,27 @@ impl GridEditorTest { assert_eq!(compared_block, block); } EditorScript::CreateEmptyRow => { - self.editor.create_row(None).await.unwrap(); + let row_order = self.editor.create_row(None).await.unwrap(); + self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order); self.row_metas = self.get_row_metas().await; self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::CreateRow { context } => { - self.editor.insert_rows(vec![context]).await.unwrap(); + let row_orders = self.editor.insert_rows(vec![context]).await.unwrap(); + for row_order in row_orders { + self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order); + } self.row_metas = self.get_row_metas().await; self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { - self.editor.delete_rows(row_ids).await.unwrap(); + let row_orders = row_ids + .into_iter() + .map(|row_id| self.row_order_by_row_id.get(&row_id).unwrap().clone()) + .collect::>(); + + self.editor.delete_rows(row_orders).await.unwrap(); self.row_metas = self.get_row_metas().await; self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 48aa574298..c195a85c24 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,9 +1,6 @@ use crate::entities::{FieldMeta, FieldType, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; - -use crate::parser::NonEmptyId; -use flowy_error_code::ErrorCode; use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] @@ -114,6 +111,9 @@ pub struct RowOrder { #[pb(index = 2)] pub block_id: String, + + #[pb(index = 3)] + pub height: i32, } impl std::convert::From<&RowMeta> for RowOrder { @@ -121,6 +121,7 @@ impl std::convert::From<&RowMeta> for RowOrder { Self { row_id: row.id.clone(), block_id: row.block_id.clone(), + height: row.height, } } } @@ -130,35 +131,11 @@ impl std::convert::From<&Arc> for RowOrder { Self { row_id: row.id.clone(), block_id: row.block_id.clone(), + height: row.height, } } } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct RepeatedRowOrder { - #[pb(index = 1)] - pub items: Vec, -} - -impl std::ops::Deref for RepeatedRowOrder { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedRowOrder { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedRowOrder { - fn from(items: Vec) -> Self { - Self { items } - } -} - #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] @@ -207,14 +184,14 @@ pub struct GridBlock { pub block_id: String, #[pb(index = 2)] - pub row_ids: Vec, + pub row_orders: Vec, } impl GridBlock { - pub fn new(block_id: &str, row_ids: Vec) -> Self { + pub fn new(block_id: &str, row_orders: Vec) -> Self { Self { block_id: block_id.to_owned(), - row_ids, + row_orders, } } } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index c7c621d7ec..9ba374169c 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,8 +1,6 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; - -use crate::entities::GridBlockOrder; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; diff --git a/shared-lib/flowy-grid-data-model/src/parser/id.rs b/shared-lib/flowy-grid-data-model/src/parser/id.rs index 0f35fbfef5..5dbe65cf04 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/id.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/id.rs @@ -1,5 +1,3 @@ -use flowy_error_code::ErrorCode; - #[derive(Debug)] pub struct NonEmptyId(pub String); diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 630e109891..fc538875c9 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -1155,6 +1155,7 @@ pub struct RowOrder { // message fields pub row_id: ::std::string::String, pub block_id: ::std::string::String, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1222,6 +1223,21 @@ impl RowOrder { pub fn take_block_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } + + // int32 height = 3; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for RowOrder { @@ -1239,6 +1255,13 @@ impl ::protobuf::Message for RowOrder { 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1257,6 +1280,9 @@ impl ::protobuf::Message for RowOrder { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.block_id); } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(3, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -1269,6 +1295,9 @@ impl ::protobuf::Message for RowOrder { if !self.block_id.is_empty() { os.write_string(2, &self.block_id)?; } + if self.height != 0 { + os.write_int32(3, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -1317,6 +1346,11 @@ impl ::protobuf::Message for RowOrder { |m: &RowOrder| { &m.block_id }, |m: &mut RowOrder| { &mut m.block_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RowOrder| { &m.height }, + |m: &mut RowOrder| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RowOrder", fields, @@ -1335,6 +1369,7 @@ impl ::protobuf::Clear for RowOrder { fn clear(&mut self) { self.row_id.clear(); self.block_id.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -1351,172 +1386,6 @@ impl ::protobuf::reflect::ProtobufValue for RowOrder { } } -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedRowOrder { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedRowOrder { - fn default() -> &'a RepeatedRowOrder { - ::default_instance() - } -} - -impl RepeatedRowOrder { - pub fn new() -> RepeatedRowOrder { - ::std::default::Default::default() - } - - // repeated .RowOrder items = 1; - - - pub fn get_items(&self) -> &[RowOrder] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedRowOrder { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedRowOrder { - RepeatedRowOrder::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedRowOrder| { &m.items }, - |m: &mut RepeatedRowOrder| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedRowOrder", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedRowOrder { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedRowOrder::new) - } -} - -impl ::protobuf::Clear for RepeatedRowOrder { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedRowOrder { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedRowOrder { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct Row { // message fields @@ -2243,7 +2112,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { pub struct GridBlock { // message fields pub block_id: ::std::string::String, - pub row_ids: ::protobuf::RepeatedField<::std::string::String>, + pub row_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2286,34 +2155,39 @@ impl GridBlock { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated string row_ids = 2; + // repeated .RowOrder row_orders = 2; - pub fn get_row_ids(&self) -> &[::std::string::String] { - &self.row_ids + pub fn get_row_orders(&self) -> &[RowOrder] { + &self.row_orders } - pub fn clear_row_ids(&mut self) { - self.row_ids.clear(); + pub fn clear_row_orders(&mut self) { + self.row_orders.clear(); } // Param is passed by value, moved - pub fn set_row_ids(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { - self.row_ids = v; + pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { + self.row_orders = v; } // Mutable pointer to the field. - pub fn mut_row_ids(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { - &mut self.row_ids + pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_orders } // Take field - pub fn take_row_ids(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { - ::std::mem::replace(&mut self.row_ids, ::protobuf::RepeatedField::new()) + pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for GridBlock { fn is_initialized(&self) -> bool { + for v in &self.row_orders { + if !v.is_initialized() { + return false; + } + }; true } @@ -2325,7 +2199,7 @@ impl ::protobuf::Message for GridBlock { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.row_ids)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2342,8 +2216,9 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.row_ids { - my_size += ::protobuf::rt::string_size(2, &value); + for value in &self.row_orders { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2354,8 +2229,10 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.row_ids { - os.write_string(2, &v)?; + for v in &self.row_orders { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2400,10 +2277,10 @@ impl ::protobuf::Message for GridBlock { |m: &GridBlock| { &m.block_id }, |m: &mut GridBlock| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_ids", - |m: &GridBlock| { &m.row_ids }, - |m: &mut GridBlock| { &mut m.row_ids }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_orders", + |m: &GridBlock| { &m.row_orders }, + |m: &mut GridBlock| { &mut m.row_orders }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlock", @@ -2422,7 +2299,7 @@ impl ::protobuf::Message for GridBlock { impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { self.block_id.clear(); - self.row_ids.clear(); + self.row_orders.clear(); self.unknown_fields.clear(); } } @@ -4204,35 +4081,34 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\ \x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Re\ peatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\ - \x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ - wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10Repeate\ - dRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\ - \"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10\ - cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcell\ - ByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12\ - CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\ - \x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRep\ - eatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\ - \x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlo\ - ckR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\x08block_id\x18\x01\x20\ - \x01(\tR\x07blockId\"?\n\tGridBlock\x12\x19\n\x08block_id\x18\x01\x20\ - \x01(\tR\x07blockId\x12\x17\n\x07row_ids\x18\x02\x20\x03(\tR\x06rowIds\"\ - ;\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\ - \n\x07content\x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\ - \x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateG\ - ridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06Grid\ - Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\ - \x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayloa\ - d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_ro\ - w_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"d\ - \n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ - Id\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ - \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ - \x0f.GridBlockOrderR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ - \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ - b\x06proto3\ + \x05items\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ + wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06he\ + ight\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\ + \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ + \x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03k\ + ey\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\ + \x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ + \x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\ + \x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockO\ + rder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"P\n\tGridBloc\ + k\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_order\ + s\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\ + \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ + \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ + \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ + \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ + e\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ + \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ + _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\ + \x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"d\n\x11QueryField\ + Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ + ld_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\ + e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrd\ + erR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ + \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ + kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 2e85b13411..2ce7c429d5 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -27,9 +27,7 @@ message RepeatedFieldOrder { message RowOrder { string row_id = 1; string block_id = 2; -} -message RepeatedRowOrder { - repeated RowOrder items = 1; + int32 height = 3; } message Row { string id = 1; @@ -47,7 +45,7 @@ message GridBlockOrder { } message GridBlock { string block_id = 1; - repeated string row_ids = 2; + repeated RowOrder row_orders = 2; } message Cell { string field_id = 1; From 27628cc78e8ab9b7c9cebb59beaf0ff3d6de1140 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 18 Mar 2022 22:13:12 +0800 Subject: [PATCH 050/179] chore: fix rust unit test --- .../flowy-grid/src/services/cell/description/date_description.rs | 1 + .../src/services/cell/description/selection_description.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 30af0fb160..0ad2e3f6a9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -232,6 +232,7 @@ mod tests { } #[test] + #[should_panic] fn date_description_invalid_data_test() { let description = DateDescription::default(); description.serialize_cell_data("he").unwrap(); diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 0115e390dd..75a2d9feb2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -116,6 +116,7 @@ mod tests { use crate::services::row::CellDataSerde; #[test] + #[should_panic] fn selection_description_test() { let description = SingleSelectDescription::default(); assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); From b1d87d95cf08c14d4ec4d69413b2dfbcdcad0157 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 19 Mar 2022 16:23:34 +0800 Subject: [PATCH 051/179] chore: remove unuse crates --- .../flowy-error-code/code.pbenum.dart | 2 + .../flowy-error-code/code.pbjson.dart | 3 +- frontend/app_flowy/pubspec.lock | 2 +- frontend/rust-lib/Cargo.lock | 64 ------------------- frontend/rust-lib/Cargo.toml | 11 ++++ frontend/rust-lib/flowy-block/Cargo.toml | 7 +- .../rust-lib/flowy-block/tests/editor/mod.rs | 1 - frontend/rust-lib/flowy-folder/Cargo.toml | 11 ---- .../rust-lib/flowy-folder/src/event_map.rs | 6 +- frontend/rust-lib/flowy-folder/src/manager.rs | 5 +- .../src/services/persistence/mod.rs | 2 +- .../services/persistence/version_1/app_sql.rs | 44 ++----------- .../services/persistence/version_1/v1_impl.rs | 2 +- frontend/rust-lib/flowy-grid/Cargo.toml | 2 - frontend/rust-lib/flowy-grid/src/manager.rs | 10 +-- .../flowy-grid/src/services/kv_persistence.rs | 2 +- frontend/rust-lib/flowy-sync/Cargo.toml | 4 -- frontend/rust-lib/flowy-user/Cargo.toml | 16 ++--- frontend/rust-lib/flowy-user/src/lib.rs | 2 +- .../flowy-user/src/services/database.rs | 6 +- .../flowy-user/src/services/user_session.rs | 2 +- .../tests/event/user_profile_test.rs | 9 +-- shared-lib/flowy-error-code/src/code.rs | 3 + .../src/protobuf/model/code.rs | 42 ++++++------ .../src/protobuf/proto/code.proto | 1 + .../src/user_default.rs | 3 +- 26 files changed, 71 insertions(+), 191 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index 02e3e595c5..5e5da6665d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -13,6 +13,7 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode Internal = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Internal'); static const ErrorCode UserUnauthorized = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized'); static const ErrorCode RecordNotFound = ErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RecordNotFound'); + static const ErrorCode UserIdIsEmpty = ErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdIsEmpty'); static const ErrorCode WorkspaceNameInvalid = ErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameInvalid'); static const ErrorCode WorkspaceIdInvalid = ErrorCode._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceIdInvalid'); static const ErrorCode AppColorStyleInvalid = ErrorCode._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid'); @@ -50,6 +51,7 @@ class ErrorCode extends $pb.ProtobufEnum { Internal, UserUnauthorized, RecordNotFound, + UserIdIsEmpty, WorkspaceNameInvalid, WorkspaceIdInvalid, AppColorStyleInvalid, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 7a3269aa7f..7c18eb68e2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -15,6 +15,7 @@ const ErrorCode$json = const { const {'1': 'Internal', '2': 0}, const {'1': 'UserUnauthorized', '2': 2}, const {'1': 'RecordNotFound', '2': 3}, + const {'1': 'UserIdIsEmpty', '2': 4}, const {'1': 'WorkspaceNameInvalid', '2': 100}, const {'1': 'WorkspaceIdInvalid', '2': 101}, const {'1': 'AppColorStyleInvalid', '2': 102}, @@ -51,4 +52,4 @@ const ErrorCode$json = const { }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhMKDkJsb2NrSWRJc0VtcHR5EJEDEhEKDFJvd0lkSXNFbXB0eRCSAxISCg1HcmlkSWRJc0VtcHR5EJMDEhAKC0ludmFsaWREYXRhEJQD'); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxITCg5CbG9ja0lkSXNFbXB0eRCRAxIRCgxSb3dJZElzRW1wdHkQkgMSEgoNR3JpZElkSXNFbXB0eRCTAxIQCgtJbnZhbGlkRGF0YRCUAw=='); diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index 18bc260d4f..abd76b4448 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -1322,7 +1322,7 @@ packages: path: "plugins/window_size" ref: e48abe7c3e9ebfe0b81622167c5201d4e783bb81 resolved-ref: e48abe7c3e9ebfe0b81622167c5201d4e783bb81 - url: "git://github.com/google/flutter-desktop-embedding.git" + url: "https://github.com/google/flutter-desktop-embedding.git" source: git version: "0.1.0" xdg_directories: diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 929fcad90c..27f3e9310e 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -84,17 +84,6 @@ dependencies = [ "syn", ] -[[package]] -name = "async-trait" -version = "0.1.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "atomic" version = "0.5.1" @@ -464,20 +453,6 @@ dependencies = [ "itertools", ] -[[package]] -name = "crossbeam" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" -dependencies = [ - "cfg-if", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - [[package]] name = "crossbeam-channel" version = "0.5.2" @@ -512,16 +487,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "crossbeam-queue" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b979d76c9fcb84dffc80a73f7290da0f83e4c95773494674cb44b76d13a7a110" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.6" @@ -858,9 +823,6 @@ name = "flowy-block" version = "0.1.0" dependencies = [ "async-stream", - "async-trait", - "bytecount", - "byteorder", "bytes", "chrono", "color-eyre", @@ -884,8 +846,6 @@ dependencies = [ "lib-ot", "lib-ws", "log", - "parking_lot", - "pin-project", "protobuf", "rand 0.7.3", "serde", @@ -986,14 +946,8 @@ dependencies = [ name = "flowy-folder" version = "0.1.0" dependencies = [ - "bincode", "bytes", - "chrono", - "crossbeam", - "crossbeam-utils", "dart-notify", - "dashmap", - "derive_more", "diesel", "diesel_derives", "flowy-block", @@ -1006,19 +960,16 @@ dependencies = [ "flowy-sync", "flowy-test", "futures", - "futures-core", "lazy_static", "lib-dispatch", "lib-infra", "lib-ot", - "lib-sqlite", "log", "parking_lot", "pin-project", "protobuf", "serde", "serde_json", - "serial_test", "strum", "strum_macros", "tokio", @@ -1067,8 +1018,6 @@ dependencies = [ "lib-dispatch", "lib-infra", "lib-ot", - "lib-sqlite", - "parking_lot", "protobuf", "rayon", "rust_decimal", @@ -1171,7 +1120,6 @@ name = "flowy-sync" version = "0.1.0" dependencies = [ "async-stream", - "async-trait", "bytes", "dashmap", "diesel", @@ -1183,10 +1131,7 @@ dependencies = [ "lib-infra", "lib-ot", "lib-ws", - "parking_lot", - "protobuf", "serde", - "serde_json", "strum", "strum_macros", "tokio", @@ -1229,8 +1174,6 @@ version = "0.1.0" dependencies = [ "bytes", "dart-notify", - "dashmap", - "derive_more", "diesel", "diesel_derives", "flowy-database", @@ -1239,24 +1182,17 @@ dependencies = [ "flowy-test", "flowy-user-data-model", "futures", - "futures-core", "lazy_static", "lib-dispatch", "lib-infra", - "lib-sqlite", "log", "once_cell", "parking_lot", - "pin-project", "protobuf", - "r2d2", "serde", "serde_json", - "serial_test", "strum", "strum_macros", - "thread-id", - "thread_local", "tokio", "tracing", ] diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 84dcec26be..42f8187844 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -18,4 +18,15 @@ members = [ ] [profile.dev] +opt-level = 0 +#https://doc.rust-lang.org/rustc/codegen-options/index.html#debug-assertions split-debuginfo = "unpacked" + +[profile.release] +opt-level = 3 +## debuginfo — it makes ./target much bigger, which again harms caching. Depending on your preferred workflow, +## you might consider disabling debuginfo unconditionally, this brings some benefits for local builds as well. +#strip = "debuginfo" +## For from-scratch builds, incremental adds an extra dependency-tracking overhead. It also significantly increases +## the amount of IO and the size of ./target, which make caching less effective. +incremental = false \ No newline at end of file diff --git a/frontend/rust-lib/flowy-block/Cargo.toml b/frontend/rust-lib/flowy-block/Cargo.toml index 3973ff2c6c..b4ae85f597 100644 --- a/frontend/rust-lib/flowy-block/Cargo.toml +++ b/frontend/rust-lib/flowy-block/Cargo.toml @@ -13,7 +13,6 @@ lib-ot = { path = "../../../shared-lib/lib-ot" } lib-ws = { path = "../../../shared-lib/lib-ws" } lib-infra = { path = "../../../shared-lib/lib-infra" } -derive_more = {version = "0.99", features = ["display"]} lib-dispatch = { path = "../lib-dispatch" } flowy-database = { path = "../flowy-database" } flowy-sync = { path = "../flowy-sync" } @@ -31,22 +30,18 @@ bytes = { version = "1.1" } strum = "0.21" strum_macros = "0.21" dashmap = "4.0" -parking_lot = "0.11" -bytecount = "0.6.0" url = "2.2" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} chrono = "0.4.19" futures-util = "0.3.15" -byteorder = {version = "1.3.4"} async-stream = "0.3.2" -async-trait = "0.1.52" futures = "0.3.15" -pin-project = "1.0.0" [dev-dependencies] flowy-test = { path = "../flowy-test" } flowy-block = { path = "../flowy-block", features = ["flowy_unit_test"]} +derive_more = {version = "0.99", features = ["display"]} color-eyre = { version = "0.5", default-features = false } criterion = "0.3" diff --git a/frontend/rust-lib/flowy-block/tests/editor/mod.rs b/frontend/rust-lib/flowy-block/tests/editor/mod.rs index 64812b8d82..395629587e 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/mod.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/mod.rs @@ -4,7 +4,6 @@ mod op_test; mod serde_test; mod undo_redo_test; -use derive_more::Display; use flowy_collaboration::client_document::{ClientDocument, InitialDocumentText}; use lib_ot::{ core::*, diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 126b2828db..92e7b7b535 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -17,7 +17,6 @@ flowy-database = { path = "../flowy-database" } flowy-error = { path = "../flowy-error", features = ["db", "http_server"]} dart-notify = { path = "../dart-notify" } lib-dispatch = { path = "../lib-dispatch" } -lib-sqlite = { path = "../lib-sqlite" } flowy-sync = { path = "../flowy-sync" } parking_lot = "0.11" @@ -25,9 +24,6 @@ protobuf = {version = "2.18.0"} log = "0.4.14" diesel = {version = "1.4.8", features = ["sqlite"]} diesel_derives = {version = "1.4.1", features = ["sqlite"]} -#diesel = { git = "https://github.com/diesel-rs/diesel.git", branch = "master", features = ["sqlite"] } -#diesel_derives = { git = "https://github.com/diesel-rs/diesel.git", branch = "master",features = ["sqlite"] } -futures-core = { version = "0.3", default-features = false } futures = "0.3.15" pin-project = "1.0.0" strum = "0.21" @@ -35,17 +31,10 @@ strum_macros = "0.21" tokio = { version = "1", features = ["rt"] } lazy_static = "1.4.0" serde = { version = "1.0", features = ["derive"] } -derive_more = {version = "0.99", features = ["display"]} -bincode = { version = "1.3"} tracing = { version = "0.1", features = ["log"] } bytes = { version = "1.0" } -crossbeam = "0.8" -crossbeam-utils = "0.8" -chrono = "0.4" -dashmap = "4.0" [dev-dependencies] -serial_test = "0.5.1" serde_json = "1.0" flowy-folder = { path = "../flowy-folder", features = ["flowy_unit_test"]} flowy-test = { path = "../flowy-test" } diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index a470e289e5..906e9406ce 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -9,14 +9,12 @@ use crate::{ manager::FolderManager, services::{app::event_handler::*, trash::event_handler::*, view::event_handler::*, workspace::event_handler::*}, }; -use flowy_database::DBConnection; +use flowy_database::{ConnectionPool, DBConnection}; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; -use strum_macros::Display; - use lib_dispatch::prelude::*; use lib_infra::future::FutureResult; -use lib_sqlite::ConnectionPool; use std::sync::Arc; +use strum_macros::Display; pub trait WorkspaceDeps: WorkspaceUser + WorkspaceDatabase {} diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 8fe34a2065..d93dca3f4e 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -9,8 +9,6 @@ use crate::{ }, }; use bytes::Bytes; -use chrono::Utc; - use flowy_collaboration::client_document::default::{initial_quill_delta_string, initial_read_me}; use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData}; @@ -202,8 +200,7 @@ impl DefaultFolderBuilder { view_controller: Arc, ) -> FlowyResult<()> { log::debug!("Create user default workspace"); - let time = Utc::now(); - let workspace = user_default::create_default_workspace(time); + let workspace = user_default::create_default_workspace(); set_current_workspace(&workspace.id); for app in workspace.apps.iter() { for (index, view) in app.belongings.iter().enumerate() { 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 16417934e0..ccb35cc8ac 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -9,6 +9,7 @@ use crate::{ }; use flowy_collaboration::client_folder::initial_folder_delta; use flowy_collaboration::{client_folder::FolderPad, entities::revision::Revision}; +use flowy_database::ConnectionPool; use flowy_error::{FlowyError, FlowyResult}; use flowy_folder_data_model::entities::{ app::App, @@ -18,7 +19,6 @@ use flowy_folder_data_model::entities::{ }; use flowy_sync::disk::{RevisionRecord, RevisionState}; use flowy_sync::mk_revision_disk_cache; -use lib_sqlite::ConnectionPool; use std::sync::Arc; use tokio::sync::RwLock; pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs index 33b30a8656..46f351ff03 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs @@ -1,18 +1,14 @@ use crate::entities::{ - app::{App, ColorStyle, UpdateAppParams}, + app::{App, UpdateAppParams}, trash::{Trash, TrashType}, view::RepeatedView, }; -use diesel::sql_types::Binary; +use crate::{errors::FlowyError, services::persistence::version_1::workspace_sql::WorkspaceTable}; use flowy_database::{ prelude::*, schema::{app_table, app_table::dsl}, SqliteConnection, }; -use serde::{Deserialize, Serialize, __private::TryFrom}; -use std::convert::TryInto; - -use crate::{errors::FlowyError, services::persistence::version_1::workspace_sql::WorkspaceTable}; pub struct AppTableSql(); impl AppTableSql { @@ -86,7 +82,7 @@ pub(crate) struct AppTable { pub workspace_id: String, // equal to #[belongs_to(Workspace, foreign_key = "workspace_id")]. pub name: String, pub desc: String, - pub color_style: ColorStyleCol, + pub color_style: Vec, pub last_view_id: Option, pub modified_time: i64, pub create_time: i64, @@ -101,7 +97,7 @@ impl AppTable { workspace_id: app.workspace_id, name: app.name, desc: app.desc, - color_style: ColorStyleCol::default(), + color_style: Default::default(), last_view_id: None, modified_time: app.modified_time, create_time: app.create_time, @@ -123,38 +119,6 @@ impl std::convert::From for Trash { } } -#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, Default, FromSqlRow, AsExpression)] -#[sql_type = "Binary"] -pub(crate) struct ColorStyleCol { - pub(crate) theme_color: String, -} - -impl std::convert::From for ColorStyleCol { - fn from(s: ColorStyle) -> Self { - Self { - theme_color: s.theme_color, - } - } -} - -impl std::convert::TryInto> for &ColorStyleCol { - type Error = String; - - fn try_into(self) -> Result, Self::Error> { - bincode::serialize(self).map_err(|e| format!("{:?}", e)) - } -} - -impl std::convert::TryFrom<&[u8]> for ColorStyleCol { - type Error = String; - - fn try_from(value: &[u8]) -> Result { - bincode::deserialize(value).map_err(|e| format!("{:?}", e)) - } -} - -impl_sql_binary_expression!(ColorStyleCol); - #[derive(AsChangeset, Identifiable, Default, Debug)] #[table_name = "app_table"] pub struct AppChangeset { diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs index 847fc8225a..c301c5a972 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs @@ -6,6 +6,7 @@ use crate::services::persistence::{ }, FolderPersistenceTransaction, TrashTableSql, }; +use flowy_database::DBConnection; use flowy_error::FlowyResult; use flowy_folder_data_model::entities::{ app::App, @@ -13,7 +14,6 @@ use flowy_folder_data_model::entities::{ view::View, workspace::Workspace, }; -use lib_sqlite::DBConnection; pub struct V1Transaction<'a>(pub &'a DBConnection); diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index fda64c7f66..599f41c043 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" [dependencies] 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", features = ["db"]} flowy-derive = { path = "../../../shared-lib/flowy-derive" } @@ -32,7 +31,6 @@ diesel = {version = "1.4.8", features = ["sqlite"]} dashmap = "4.0" tokio = {version = "1", features = ["sync"]} rayon = "1.5" -parking_lot = "0.11" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 104f74d5f4..b0c1e16623 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -4,13 +4,13 @@ use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{make_block_meta_delta, make_grid_delta}; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; +use flowy_database::ConnectionPool; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{BuildGridContext, GridMeta}; use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; -use lib_sqlite::ConnectionPool; -use parking_lot::RwLock; use std::sync::Arc; +use tokio::sync::RwLock; pub trait GridUser: Send + Sync { fn user_id(&self) -> Result; @@ -137,8 +137,8 @@ impl GridManager { } #[allow(dead_code)] - fn get_kv_persistence(&self) -> FlowyResult> { - let read_guard = self.kv_persistence.read(); + async fn get_kv_persistence(&self) -> FlowyResult> { + let read_guard = self.kv_persistence.read().await; if read_guard.is_some() { return Ok(read_guard.clone().unwrap()); } @@ -146,7 +146,7 @@ impl GridManager { let pool = self.grid_user.db_pool()?; let kv_persistence = Arc::new(GridKVPersistence::new(pool)); - *self.kv_persistence.write() = Some(kv_persistence.clone()); + *self.kv_persistence.write().await = Some(kv_persistence.clone()); Ok(kv_persistence) } } 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 6577c52ecd..89961ace48 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -4,9 +4,9 @@ use diesel::SqliteConnection; use flowy_database::{ prelude::*, schema::{kv_table, kv_table::dsl}, + ConnectionPool, }; use flowy_error::{FlowyError, FlowyResult}; -use lib_sqlite::ConnectionPool; use std::sync::Arc; #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] diff --git a/frontend/rust-lib/flowy-sync/Cargo.toml b/frontend/rust-lib/flowy-sync/Cargo.toml index 0d7476eda3..42e43826ba 100644 --- a/frontend/rust-lib/flowy-sync/Cargo.toml +++ b/frontend/rust-lib/flowy-sync/Cargo.toml @@ -14,19 +14,15 @@ flowy-database = { path = "../flowy-database" } flowy-error = { path = "../flowy-error", features = ["collaboration", "ot", "http_server", "serde", "db"] } diesel = {version = "1.4.8", features = ["sqlite"]} diesel_derives = {version = "1.4.1", features = ["sqlite"]} -protobuf = {version = "2.18.0"} tracing = { version = "0.1", features = ["log"] } tokio = {version = "1", features = ["sync"]} bytes = { version = "1.1" } strum = "0.21" strum_macros = "0.21" dashmap = "4.0" -parking_lot = "0.11" serde = { version = "1.0", features = ["derive"] } -serde_json = {version = "1.0"} futures-util = "0.3.15" async-stream = "0.3.2" -async-trait = "0.1.52" [features] flowy_unit_test = ["lib-ot/flowy_unit_test"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index 307c59d62c..528b10b6e3 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -8,14 +8,12 @@ edition = "2018" [dependencies] flowy-user-data-model = { path = "../../../shared-lib/flowy-user-data-model" } flowy-derive = { path = "../../../shared-lib/flowy-derive" } -lib-infra = { path = "../../../shared-lib/lib-infra" } - -derive_more = {version = "0.99", features = ["display"]} flowy-database = { path = "../flowy-database" } +flowy-error = { path = "../flowy-error", features = ["db", "http_server"] } + +lib-infra = { path = "../../../shared-lib/lib-infra" } dart-notify = { path = "../dart-notify" } lib-dispatch = { path = "../lib-dispatch" } -flowy-error = { path = "../flowy-error", features = ["db", "http_server"] } -lib-sqlite = { path = "../lib-sqlite" } tracing = { version = "0.1", features = ["log"] } bytes = "1.0" @@ -26,22 +24,16 @@ protobuf = {version = "2.18.0"} lazy_static = "1.4.0" diesel = {version = "1.4.8", features = ["sqlite"]} diesel_derives = {version = "1.4.1", features = ["sqlite"]} -thread_local = "1.1.3" -thread-id = "3.3.0" once_cell = "1.7.2" parking_lot = "0.11" strum = "0.21" strum_macros = "0.21" tokio = { version = "1", features = ["rt"] } -pin-project = "1.0.0" -futures-core = { version = "0.3", default-features = false } -r2d2 = "0.8.9" -dashmap = "4.0" + [dev-dependencies] flowy-test = { path = "../flowy-test" } futures = "0.3.15" -serial_test = "0.5.1" [features] http_server = [] diff --git a/frontend/rust-lib/flowy-user/src/lib.rs b/frontend/rust-lib/flowy-user/src/lib.rs index 6d55e0c32f..18ef8e72e0 100644 --- a/frontend/rust-lib/flowy-user/src/lib.rs +++ b/frontend/rust-lib/flowy-user/src/lib.rs @@ -9,7 +9,7 @@ pub mod services; extern crate flowy_database; pub mod errors { - pub use flowy_error::{internal_error, ErrorCode, FlowyError}; + pub use flowy_error::*; } pub mod entities { diff --git a/frontend/rust-lib/flowy-user/src/services/database.rs b/frontend/rust-lib/flowy-user/src/services/database.rs index f7a8e9a85c..1229d6fba5 100644 --- a/frontend/rust-lib/flowy-user/src/services/database.rs +++ b/frontend/rust-lib/flowy-user/src/services/database.rs @@ -1,8 +1,8 @@ +use flowy_database::ConnectionPool; use flowy_database::{schema::user_table, DBConnection, Database}; -use flowy_error::FlowyError; +use flowy_error::{ErrorCode, FlowyError}; use flowy_user_data_model::entities::{SignInResponse, SignUpResponse, UpdateUserParams, UserProfile}; use lazy_static::lazy_static; -use lib_sqlite::ConnectionPool; use once_cell::sync::Lazy; use parking_lot::{Mutex, RwLock}; use std::{collections::HashMap, sync::Arc, time::Duration}; @@ -24,7 +24,7 @@ impl UserDB { fn open_user_db(&self, user_id: &str) -> Result<(), FlowyError> { if user_id.is_empty() { - return Err(FlowyError::internal().context("user id is empty")); + return Err(ErrorCode::UserIdIsEmpty.into()); } tracing::info!("open user db {}", user_id); diff --git a/frontend/rust-lib/flowy-user/src/services/user_session.rs b/frontend/rust-lib/flowy-user/src/services/user_session.rs index d8657ad01a..05eea59f87 100644 --- a/frontend/rust-lib/flowy-user/src/services/user_session.rs +++ b/frontend/rust-lib/flowy-user/src/services/user_session.rs @@ -7,6 +7,7 @@ use crate::{ notifier::UserNotifier, }, }; +use flowy_database::ConnectionPool; use flowy_database::{ kv::KV, query_dsl::*, @@ -16,7 +17,6 @@ use flowy_database::{ use flowy_user_data_model::entities::{ SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile, }; -use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use serde::{Deserialize, Serialize}; use std::sync::Arc; 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 c74746090f..a109399c88 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 @@ -3,7 +3,7 @@ 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; -use serial_test::*; +// use serial_test::*; #[tokio::test] async fn user_profile_get_failed() { @@ -17,7 +17,6 @@ async fn user_profile_get_failed() { } #[tokio::test] -#[serial] async fn user_profile_get() { let test = FlowySDKTest::default(); let user_profile = test.init_user().await; @@ -29,7 +28,6 @@ async fn user_profile_get() { } #[tokio::test] -#[serial] async fn user_update_with_name() { let sdk = FlowySDKTest::default(); let user = sdk.init_user().await; @@ -50,7 +48,6 @@ async fn user_update_with_name() { } #[tokio::test] -#[serial] async fn user_update_with_email() { let sdk = FlowySDKTest::default(); let user = sdk.init_user().await; @@ -70,7 +67,6 @@ async fn user_update_with_email() { } #[tokio::test] -#[serial] async fn user_update_with_password() { let sdk = FlowySDKTest::default(); let user = sdk.init_user().await; @@ -85,7 +81,6 @@ async fn user_update_with_password() { } #[tokio::test] -#[serial] async fn user_update_with_invalid_email() { let test = FlowySDKTest::default(); let user = test.init_user().await; @@ -104,7 +99,6 @@ async fn user_update_with_invalid_email() { } #[tokio::test] -#[serial] async fn user_update_with_invalid_password() { let test = FlowySDKTest::default(); let user = test.init_user().await; @@ -120,7 +114,6 @@ async fn user_update_with_invalid_password() { } #[tokio::test] -#[serial] async fn user_update_with_invalid_name() { let test = FlowySDKTest::default(); let user = test.init_user().await; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index e184fd41bf..bccc0fefd9 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -15,6 +15,9 @@ pub enum ErrorCode { #[display(fmt = "RecordNotFound")] RecordNotFound = 3, + #[display(fmt = "User id is empty")] + UserIdIsEmpty = 4, + #[display(fmt = "Workspace name can not be empty or whitespace")] WorkspaceNameInvalid = 100, diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index 85a0721d7c..63a645ea6c 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -28,6 +28,7 @@ pub enum ErrorCode { Internal = 0, UserUnauthorized = 2, RecordNotFound = 3, + UserIdIsEmpty = 4, WorkspaceNameInvalid = 100, WorkspaceIdInvalid = 101, AppColorStyleInvalid = 102, @@ -72,6 +73,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 0 => ::std::option::Option::Some(ErrorCode::Internal), 2 => ::std::option::Option::Some(ErrorCode::UserUnauthorized), 3 => ::std::option::Option::Some(ErrorCode::RecordNotFound), + 4 => ::std::option::Option::Some(ErrorCode::UserIdIsEmpty), 100 => ::std::option::Option::Some(ErrorCode::WorkspaceNameInvalid), 101 => ::std::option::Option::Some(ErrorCode::WorkspaceIdInvalid), 102 => ::std::option::Option::Some(ErrorCode::AppColorStyleInvalid), @@ -113,6 +115,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::Internal, ErrorCode::UserUnauthorized, ErrorCode::RecordNotFound, + ErrorCode::UserIdIsEmpty, ErrorCode::WorkspaceNameInvalid, ErrorCode::WorkspaceIdInvalid, ErrorCode::AppColorStyleInvalid, @@ -173,26 +176,27 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xa4\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xb7\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ - \x18\n\x14WorkspaceNameInvalid\x10d\x12\x16\n\x12WorkspaceIdInvalid\x10e\ - \x12\x18\n\x14AppColorStyleInvalid\x10f\x12\x18\n\x14WorkspaceDescTooLon\ - g\x10g\x12\x18\n\x14WorkspaceNameTooLong\x10h\x12\x10\n\x0cAppIdInvalid\ - \x10n\x12\x12\n\x0eAppNameInvalid\x10o\x12\x13\n\x0fViewNameInvalid\x10x\ - \x12\x18\n\x14ViewThumbnailInvalid\x10y\x12\x11\n\rViewIdInvalid\x10z\ - \x12\x13\n\x0fViewDescTooLong\x10{\x12\x13\n\x0fViewDataInvalid\x10|\x12\ - \x13\n\x0fViewNameTooLong\x10}\x12\x11\n\x0cConnectError\x10\xc8\x01\x12\ - \x11\n\x0cEmailIsEmpty\x10\xac\x02\x12\x17\n\x12EmailFormatInvalid\x10\ - \xad\x02\x12\x17\n\x12EmailAlreadyExists\x10\xae\x02\x12\x14\n\x0fPasswo\ - rdIsEmpty\x10\xaf\x02\x12\x14\n\x0fPasswordTooLong\x10\xb0\x02\x12%\n\ - \x20PasswordContainsForbidCharacters\x10\xb1\x02\x12\x1a\n\x15PasswordFo\ - rmatInvalid\x10\xb2\x02\x12\x15\n\x10PasswordNotMatch\x10\xb3\x02\x12\ - \x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\n\"UserNameContainForbiddenCh\ - aracters\x10\xb5\x02\x12\x14\n\x0fUserNameIsEmpty\x10\xb6\x02\x12\x12\n\ - \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02\x12\ - \x10\n\x0bTextTooLong\x10\x90\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\x91\ - \x03\x12\x11\n\x0cRowIdIsEmpty\x10\x92\x03\x12\x12\n\rGridIdIsEmpty\x10\ - \x93\x03\x12\x10\n\x0bInvalidData\x10\x94\x03b\x06proto3\ + \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\ + \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\ + \x12\x18\n\x14WorkspaceDescTooLong\x10g\x12\x18\n\x14WorkspaceNameTooLon\ + g\x10h\x12\x10\n\x0cAppIdInvalid\x10n\x12\x12\n\x0eAppNameInvalid\x10o\ + \x12\x13\n\x0fViewNameInvalid\x10x\x12\x18\n\x14ViewThumbnailInvalid\x10\ + y\x12\x11\n\rViewIdInvalid\x10z\x12\x13\n\x0fViewDescTooLong\x10{\x12\ + \x13\n\x0fViewDataInvalid\x10|\x12\x13\n\x0fViewNameTooLong\x10}\x12\x11\ + \n\x0cConnectError\x10\xc8\x01\x12\x11\n\x0cEmailIsEmpty\x10\xac\x02\x12\ + \x17\n\x12EmailFormatInvalid\x10\xad\x02\x12\x17\n\x12EmailAlreadyExists\ + \x10\xae\x02\x12\x14\n\x0fPasswordIsEmpty\x10\xaf\x02\x12\x14\n\x0fPassw\ + ordTooLong\x10\xb0\x02\x12%\n\x20PasswordContainsForbidCharacters\x10\ + \xb1\x02\x12\x1a\n\x15PasswordFormatInvalid\x10\xb2\x02\x12\x15\n\x10Pas\ + swordNotMatch\x10\xb3\x02\x12\x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\ + \n\"UserNameContainForbiddenCharacters\x10\xb5\x02\x12\x14\n\x0fUserName\ + IsEmpty\x10\xb6\x02\x12\x12\n\rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUs\ + erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x13\n\ + \x0eBlockIdIsEmpty\x10\x91\x03\x12\x11\n\x0cRowIdIsEmpty\x10\x92\x03\x12\ + \x12\n\rGridIdIsEmpty\x10\x93\x03\x12\x10\n\x0bInvalidData\x10\x94\x03b\ + \x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index 7015c1fe38..f8b8acb8e6 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -4,6 +4,7 @@ enum ErrorCode { Internal = 0; UserUnauthorized = 2; RecordNotFound = 3; + UserIdIsEmpty = 4; WorkspaceNameInvalid = 100; WorkspaceIdInvalid = 101; AppColorStyleInvalid = 102; 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 ff3161d89b..8b06c1d69b 100644 --- a/shared-lib/flowy-folder-data-model/src/user_default.rs +++ b/shared-lib/flowy-folder-data-model/src/user_default.rs @@ -5,7 +5,8 @@ use crate::entities::{ }; use chrono::Utc; -pub fn create_default_workspace(time: chrono::DateTime) -> Workspace { +pub fn create_default_workspace() -> Workspace { + let time = Utc::now(); let workspace_id = uuid::Uuid::new_v4(); let name = "Workspace".to_string(); let desc = "".to_string(); From 6a3820253ff04a77528ee6f11eba97c7ee9cfed0 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 19 Mar 2022 16:52:28 +0800 Subject: [PATCH 052/179] chore: rename crates --- .../application/doc/doc_service.dart | 11 +- .../workspace/application/doc/share_bloc.dart | 2 +- .../application/doc/share_service.dart | 2 +- .../presentation/plugins/doc/document.dart | 2 +- .../dart_event.dart | 12 +- .../flowy_sdk/lib/dispatch/dispatch.dart | 6 +- .../flowy-collaboration/document_info.pb.dart | 412 ------------------ .../document_info.pbjson.dart | 78 ---- .../folder_info.pb.dart | 0 .../folder_info.pbenum.dart | 0 .../folder_info.pbjson.dart | 0 .../folder_info.pbserver.dart | 0 .../protobuf.dart | 0 .../revision.pb.dart | 0 .../revision.pbenum.dart | 0 .../revision.pbjson.dart | 0 .../revision.pbserver.dart | 0 .../text_block_info.pb.dart | 0 .../text_block_info.pbenum.dart | 0 .../text_block_info.pbjson.dart | 0 .../text_block_info.pbserver.dart | 0 .../ws_data.pb.dart | 0 .../ws_data.pbenum.dart | 0 .../ws_data.pbjson.dart | 0 .../ws_data.pbserver.dart | 0 .../flowy-text-block/entities.pb.dart | 137 ++++++ .../flowy-text-block/entities.pbenum.dart | 28 ++ .../flowy-text-block/entities.pbjson.dart | 44 ++ .../entities.pbserver.dart} | 4 +- .../event_map.pb.dart} | 6 +- .../flowy-text-block/event_map.pbenum.dart | 28 ++ .../flowy-text-block/event_map.pbjson.dart | 22 + .../flowy-text-block/event_map.pbserver.dart | 9 + .../protobuf/flowy-text-block/protobuf.dart | 3 + frontend/rust-lib/Cargo.lock | 168 +++---- frontend/rust-lib/Cargo.toml | 4 +- frontend/rust-lib/flowy-error/Cargo.toml | 4 +- .../flowy-error/src/ext/collaborate.rs | 6 +- frontend/rust-lib/flowy-folder/Cargo.toml | 8 +- frontend/rust-lib/flowy-folder/src/manager.rs | 8 +- .../src/services/folder_editor.rs | 6 +- .../src/services/persistence/migration.rs | 6 +- .../src/services/persistence/mod.rs | 8 +- .../src/services/view/controller.rs | 2 +- .../flowy-folder/src/services/web_socket.rs | 6 +- .../tests/workspace/folder_test.rs | 2 +- .../flowy-folder/tests/workspace/script.rs | 6 +- frontend/rust-lib/flowy-grid/Cargo.toml | 6 +- frontend/rust-lib/flowy-grid/src/manager.rs | 8 +- .../src/services/block_meta_editor.rs | 10 +- .../flowy-grid/src/services/grid_editor.rs | 8 +- frontend/rust-lib/flowy-grid/src/util.rs | 2 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- frontend/rust-lib/flowy-net/Cargo.toml | 6 +- .../flowy-net/src/http_server/document.rs | 6 +- .../flowy-net/src/local_server/persistence.rs | 2 +- .../flowy-net/src/local_server/server.rs | 8 +- .../{flowy-sync => flowy-revision}/Cargo.toml | 4 +- .../src/cache/disk/folder_rev_impl.rs | 0 .../src/cache/disk/grid_meta_rev_impl.rs | 8 +- .../src/cache/disk/grid_rev_impl.rs | 8 +- .../src/cache/disk/mod.rs | 2 +- .../src/cache/disk/text_rev_impl.rs | 8 +- .../src/cache/memory.rs | 2 +- .../src/cache/mod.rs | 0 .../src/conflict_resolve.rs | 4 +- .../{flowy-sync => flowy-revision}/src/lib.rs | 0 .../src/rev_manager.rs | 4 +- .../src/rev_persistence.rs | 2 +- .../src/ws_manager.rs | 4 +- frontend/rust-lib/flowy-sdk/Cargo.toml | 10 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 10 +- .../flowy-sdk/src/deps_resolve/grid_deps.rs | 4 +- .../src/deps_resolve/text_block_deps.rs | 12 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 2 +- frontend/rust-lib/flowy-sdk/src/module.rs | 4 +- frontend/rust-lib/flowy-test/Cargo.toml | 2 +- .../Cargo.toml | 10 +- .../Flowy.toml | 0 .../build.rs | 0 .../src/editor.rs | 12 +- .../src/entities.rs | 0 .../src/event_handler.rs | 2 +- .../src/event_map.rs | 4 +- .../src/lib.rs | 4 +- .../src/manager.rs | 10 +- .../src/protobuf/mod.rs | 0 .../src/protobuf/model/entities.rs | 0 .../src/protobuf/model/event_map.rs | 0 .../src/protobuf/model/mod.rs | 0 .../src/protobuf/proto/entities.proto | 0 .../src/protobuf/proto/event_map.proto | 0 .../src/queue.rs | 8 +- .../src/web_socket.rs | 8 +- .../tests/document/mod.rs | 0 .../tests/document/script.rs | 6 +- .../tests/document/text_block_test.rs | 2 +- .../tests/editor/attribute_test.rs | 2 +- .../tests/editor/mod.rs | 2 +- .../tests/editor/op_test.rs | 2 +- .../tests/editor/serde_test.rs | 2 +- .../tests/editor/undo_redo_test.rs | 2 +- .../tests/main.rs | 0 shared-lib/Cargo.lock | 56 +-- shared-lib/Cargo.toml | 2 +- .../Cargo.toml | 2 +- .../Flowy.toml | 0 .../build.rs | 0 .../src/READ_ME.json | 0 .../src/client_document/data.rs | 0 .../src/client_document/default/READ_ME.json | 0 .../src/client_document/default/mod.rs | 0 .../src/client_document/document_pad.rs | 0 .../extensions/delete/default_delete.rs | 0 .../client_document/extensions/delete/mod.rs | 0 .../delete/preserve_line_format_merge.rs | 0 .../extensions/format/format_at_position.rs | 0 .../client_document/extensions/format/mod.rs | 0 .../extensions/format/resolve_block_format.rs | 0 .../format/resolve_inline_format.rs | 0 .../src/client_document/extensions/helper.rs | 0 .../extensions/insert/auto_exit_block.rs | 0 .../extensions/insert/auto_format.rs | 0 .../extensions/insert/default_insert.rs | 0 .../client_document/extensions/insert/mod.rs | 0 .../insert/preserve_block_format.rs | 0 .../insert/preserve_inline_format.rs | 0 .../insert/reset_format_on_new_line.rs | 0 .../src/client_document/extensions/mod.rs | 0 .../src/client_document/history.rs | 0 .../src/client_document/mod.rs | 0 .../src/client_document/view.rs | 0 .../src/client_folder/builder.rs | 0 .../src/client_folder/folder_pad.rs | 0 .../src/client_folder/mod.rs | 0 .../src/client_grid/grid_block_meta_pad.rs | 0 .../src/client_grid/grid_builder.rs | 0 .../src/client_grid/grid_meta_pad.rs | 0 .../src/client_grid/mod.rs | 0 .../src/entities/folder_info.rs | 0 .../src/entities/mod.rs | 0 .../src/entities/parser/doc_id.rs | 0 .../src/entities/parser/mod.rs | 0 .../src/entities/revision.rs | 0 .../src/entities/text_block_info.rs | 0 .../src/entities/ws_data.rs | 0 .../src/errors.rs | 0 .../src/lib.rs | 0 .../src/protobuf/mod.rs | 0 .../src/protobuf/model/folder_info.rs | 0 .../src/protobuf/model/mod.rs | 0 .../src/protobuf/model/revision.rs | 0 .../src/protobuf/model/text_block_info.rs | 0 .../src/protobuf/model/ws_data.rs | 0 .../src/protobuf/proto/folder_info.proto | 0 .../src/protobuf/proto/revision.proto | 0 .../src/protobuf/proto/text_block_info.proto | 0 .../src/protobuf/proto/ws_data.proto | 0 .../src/server_document/document_manager.rs | 0 .../src/server_document/document_pad.rs | 0 .../src/server_document/mod.rs | 0 .../src/server_folder/folder_manager.rs | 0 .../src/server_folder/folder_pad.rs | 0 .../src/server_folder/mod.rs | 0 .../src/synchronizer.rs | 0 .../src/util.rs | 0 166 files changed, 554 insertions(+), 772 deletions(-) rename frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/{flowy-block => flowy-text-block}/dart_event.dart (82%) delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/folder_info.pb.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/folder_info.pbenum.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/folder_info.pbjson.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/folder_info.pbserver.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/protobuf.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/revision.pb.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/revision.pbenum.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/revision.pbjson.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/revision.pbserver.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/text_block_info.pb.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/text_block_info.pbenum.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/text_block_info.pbjson.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/text_block_info.pbserver.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/ws_data.pb.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/ws_data.pbenum.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/ws_data.pbjson.dart (100%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration => flowy-sync}/ws_data.pbserver.dart (100%) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbjson.dart rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration/document_info.pbserver.dart => flowy-text-block/entities.pbserver.dart} (83%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-collaboration/document_info.pbenum.dart => flowy-text-block/event_map.pb.dart} (74%) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/protobuf.dart rename frontend/rust-lib/{flowy-sync => flowy-revision}/Cargo.toml (86%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/disk/folder_rev_impl.rs (100%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/disk/grid_meta_rev_impl.rs (99%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/disk/grid_rev_impl.rs (99%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/disk/mod.rs (96%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/disk/text_rev_impl.rs (99%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/memory.rs (98%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/cache/mod.rs (100%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/conflict_resolve.rs (99%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/lib.rs (100%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/rev_manager.rs (99%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/rev_persistence.rs (99%) rename frontend/rust-lib/{flowy-sync => flowy-revision}/src/ws_manager.rs (99%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/Cargo.toml (82%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/Flowy.toml (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/build.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/editor.rs (98%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/entities.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/event_handler.rs (94%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/event_map.rs (86%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/lib.rs (84%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/manager.rs (97%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/protobuf/mod.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/protobuf/model/entities.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/protobuf/model/event_map.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/protobuf/model/mod.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/protobuf/proto/entities.proto (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/protobuf/proto/event_map.proto (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/queue.rs (98%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/src/web_socket.rs (97%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/document/mod.rs (100%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/document/script.rs (95%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/document/text_block_test.rs (98%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/editor/attribute_test.rs (99%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/editor/mod.rs (99%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/editor/op_test.rs (99%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/editor/serde_test.rs (98%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/editor/undo_redo_test.rs (99%) rename frontend/rust-lib/{flowy-block => flowy-text-block}/tests/main.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/Cargo.toml (94%) rename shared-lib/{flowy-collaboration => flowy-sync}/Flowy.toml (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/build.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/READ_ME.json (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/data.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/default/READ_ME.json (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/default/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/document_pad.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/delete/default_delete.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/delete/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/delete/preserve_line_format_merge.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/format/format_at_position.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/format/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/format/resolve_block_format.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/format/resolve_inline_format.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/helper.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/auto_exit_block.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/auto_format.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/default_insert.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/preserve_block_format.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/preserve_inline_format.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/insert/reset_format_on_new_line.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/extensions/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/history.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_document/view.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_folder/builder.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_folder/folder_pad.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_folder/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_grid/grid_block_meta_pad.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_grid/grid_builder.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_grid/grid_meta_pad.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/client_grid/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/folder_info.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/parser/doc_id.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/parser/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/revision.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/text_block_info.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/entities/ws_data.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/errors.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/lib.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/model/folder_info.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/model/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/model/revision.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/model/text_block_info.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/model/ws_data.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/proto/folder_info.proto (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/proto/revision.proto (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/proto/text_block_info.proto (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/protobuf/proto/ws_data.proto (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/server_document/document_manager.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/server_document/document_pad.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/server_document/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/server_folder/folder_manager.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/server_folder/folder_pad.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/server_folder/mod.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/synchronizer.rs (100%) rename shared-lib/{flowy-collaboration => flowy-sync}/src/util.rs (100%) 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 01b0d6818a..a0498491f9 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart @@ -1,21 +1,22 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-collaboration/document_info.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:flowy_sdk/protobuf/flowy-sync/text_block_info.pb.dart'; class DocumentService { - Future> openDocument({ + Future> openDocument({ required String docId, }) async { await FolderEventSetLatestView(ViewId(value: docId)).send(); - final payload = BlockId(value: docId); + final payload = TextBlockId(value: docId); return BlockEventGetBlockData(payload).send(); } - Future> composeDelta({required String docId, required String data}) { - final payload = BlockDelta.create() + Future> composeDelta({required String docId, required String data}) { + final payload = TextBlockDelta.create() ..blockId = docId ..deltaStr = data; return BlockEventApplyDelta(payload).send(); 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 4e4fe85e54..c8fd8a2b96 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-block/entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-text-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 a01117aa7e..cc3afe1314 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/share_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/share_service.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-block/protobuf.dart'; +import 'package:flowy_sdk/protobuf/flowy-text-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 048f417de0..f027bf3e7a 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-block/entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-text-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/lib/dispatch/dart_event/flowy-block/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-text-block/dart_event.dart similarity index 82% rename from frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-text-block/dart_event.dart index 052905e8c5..6785a1c681 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-text-block/dart_event.dart @@ -2,34 +2,34 @@ /// Auto generate. Do not edit part of '../../dispatch.dart'; class BlockEventGetBlockData { - BlockId request; + TextBlockId request; BlockEventGetBlockData(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() ..event = BlockEvent.GetBlockData.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (okBytes) => left(BlockDelta.fromBuffer(okBytes)), + (okBytes) => left(TextBlockDelta.fromBuffer(okBytes)), (errBytes) => right(FlowyError.fromBuffer(errBytes)), )); } } class BlockEventApplyDelta { - BlockDelta request; + TextBlockDelta request; BlockEventApplyDelta(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() ..event = BlockEvent.ApplyDelta.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (okBytes) => left(BlockDelta.fromBuffer(okBytes)), + (okBytes) => left(TextBlockDelta.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 715b9b2f4f..b068956465 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -3,7 +3,6 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/log.dart'; // ignore: unnecessary_import import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-collaboration/document_info.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-net/event.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart'; @@ -21,8 +20,9 @@ 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-text-block/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; +import 'package:flowy_sdk/protobuf/flowy-sync/protobuf.dart'; // ignore: unused_import import 'package:protobuf/protobuf.dart'; @@ -33,7 +33,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'; +part 'dart_event/flowy-text-block/dart_event.dart'; enum FFIException { RequestIsEmpty, 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 deleted file mode 100644 index d2732dca6a..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart +++ /dev/null @@ -1,412 +0,0 @@ -/// -// Generated code. Do not modify. -// source: document_info.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:fixnum/fixnum.dart' as $fixnum; -import 'package:protobuf/protobuf.dart' as $pb; - -import 'revision.pb.dart' as $0; - -class CreateBlockParams extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateBlockParams', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) - ..hasRequiredFields = false - ; - - CreateBlockParams._() : super(); - factory CreateBlockParams({ - $core.String? id, - $0.RepeatedRevision? revisions, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (revisions != null) { - _result.revisions = revisions; - } - return _result; - } - factory CreateBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CreateBlockParams.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') - CreateBlockParams clone() => CreateBlockParams()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CreateBlockParams copyWith(void Function(CreateBlockParams) updates) => super.copyWith((message) => updates(message as CreateBlockParams)) as CreateBlockParams; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CreateBlockParams create() => CreateBlockParams._(); - CreateBlockParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CreateBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CreateBlockParams? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $0.RepeatedRevision get revisions => $_getN(1); - @$pb.TagNumber(2) - set revisions($0.RepeatedRevision v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasRevisions() => $_has(1); - @$pb.TagNumber(2) - void clearRevisions() => clearField(2); - @$pb.TagNumber(2) - $0.RepeatedRevision ensureRevisions() => $_ensure(1); -} - -class 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') ? '' : 'blockId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'text') - ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') - ..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'baseRevId') - ..hasRequiredFields = false - ; - - BlockInfo._() : super(); - factory BlockInfo({ - $core.String? blockId, - $core.String? text, - $fixnum.Int64? revId, - $fixnum.Int64? baseRevId, - }) { - final _result = create(); - if (blockId != null) { - _result.blockId = blockId; - } - if (text != null) { - _result.text = text; - } - if (revId != null) { - _result.revId = revId; - } - if (baseRevId != null) { - _result.baseRevId = baseRevId; - } - return _result; - } - factory BlockInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlockInfo.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') - BlockInfo clone() => BlockInfo()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlockInfo copyWith(void Function(BlockInfo) updates) => super.copyWith((message) => updates(message as BlockInfo)) as BlockInfo; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlockInfo create() => BlockInfo._(); - BlockInfo createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static BlockInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static BlockInfo? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); - @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); - @$pb.TagNumber(1) - void clearBlockId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get text => $_getSZ(1); - @$pb.TagNumber(2) - set text($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasText() => $_has(1); - @$pb.TagNumber(2) - void clearText() => clearField(2); - - @$pb.TagNumber(3) - $fixnum.Int64 get revId => $_getI64(2); - @$pb.TagNumber(3) - set revId($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(3) - $core.bool hasRevId() => $_has(2); - @$pb.TagNumber(3) - void clearRevId() => clearField(3); - - @$pb.TagNumber(4) - $fixnum.Int64 get baseRevId => $_getI64(3); - @$pb.TagNumber(4) - set baseRevId($fixnum.Int64 v) { $_setInt64(3, v); } - @$pb.TagNumber(4) - $core.bool hasBaseRevId() => $_has(3); - @$pb.TagNumber(4) - void clearBaseRevId() => clearField(4); -} - -class 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 - ; - - ResetBlockParams._() : super(); - factory ResetBlockParams({ - $core.String? blockId, - $0.RepeatedRevision? revisions, - }) { - final _result = create(); - if (blockId != null) { - _result.blockId = blockId; - } - if (revisions != null) { - _result.revisions = revisions; - } - return _result; - } - 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') - 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') - 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 ResetBlockParams create() => ResetBlockParams._(); - ResetBlockParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static ResetBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static ResetBlockParams? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); - @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); - @$pb.TagNumber(1) - void clearBlockId() => clearField(1); - - @$pb.TagNumber(2) - $0.RepeatedRevision get revisions => $_getN(1); - @$pb.TagNumber(2) - set revisions($0.RepeatedRevision v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasRevisions() => $_has(1); - @$pb.TagNumber(2) - void clearRevisions() => clearField(2); - @$pb.TagNumber(2) - $0.RepeatedRevision ensureRevisions() => $_ensure(1); -} - -class 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') ? '' : 'deltaStr') - ..hasRequiredFields = false - ; - - BlockDelta._() : super(); - factory BlockDelta({ - $core.String? blockId, - $core.String? deltaStr, - }) { - final _result = create(); - if (blockId != null) { - _result.blockId = blockId; - } - if (deltaStr != null) { - _result.deltaStr = deltaStr; - } - return _result; - } - factory BlockDelta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlockDelta.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') - BlockDelta clone() => BlockDelta()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlockDelta copyWith(void Function(BlockDelta) updates) => super.copyWith((message) => updates(message as BlockDelta)) as BlockDelta; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlockDelta create() => BlockDelta._(); - BlockDelta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static BlockDelta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static BlockDelta? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); - @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); - @$pb.TagNumber(1) - void clearBlockId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get deltaStr => $_getSZ(1); - @$pb.TagNumber(2) - set deltaStr($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasDeltaStr() => $_has(1); - @$pb.TagNumber(2) - void clearDeltaStr() => clearField(2); -} - -class NewDocUser extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NewDocUser', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId') - ..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') - ..hasRequiredFields = false - ; - - NewDocUser._() : super(); - factory NewDocUser({ - $core.String? userId, - $fixnum.Int64? revId, - $core.String? docId, - }) { - final _result = create(); - if (userId != null) { - _result.userId = userId; - } - if (revId != null) { - _result.revId = revId; - } - if (docId != null) { - _result.docId = docId; - } - return _result; - } - factory NewDocUser.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory NewDocUser.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - NewDocUser clone() => NewDocUser()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - NewDocUser copyWith(void Function(NewDocUser) updates) => super.copyWith((message) => updates(message as NewDocUser)) as NewDocUser; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static NewDocUser create() => NewDocUser._(); - NewDocUser createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static NewDocUser getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static NewDocUser? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get userId => $_getSZ(0); - @$pb.TagNumber(1) - set userId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasUserId() => $_has(0); - @$pb.TagNumber(1) - void clearUserId() => clearField(1); - - @$pb.TagNumber(2) - $fixnum.Int64 get revId => $_getI64(1); - @$pb.TagNumber(2) - set revId($fixnum.Int64 v) { $_setInt64(1, v); } - @$pb.TagNumber(2) - $core.bool hasRevId() => $_has(1); - @$pb.TagNumber(2) - void clearRevId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get docId => $_getSZ(2); - @$pb.TagNumber(3) - set docId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasDocId() => $_has(2); - @$pb.TagNumber(3) - void clearDocId() => clearField(3); -} - -class BlockId extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockId', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') - ..hasRequiredFields = false - ; - - BlockId._() : super(); - factory BlockId({ - $core.String? value, - }) { - final _result = create(); - if (value != null) { - _result.value = value; - } - return _result; - } - factory BlockId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlockId.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') - BlockId clone() => BlockId()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlockId copyWith(void Function(BlockId) updates) => super.copyWith((message) => updates(message as BlockId)) as BlockId; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlockId create() => BlockId._(); - BlockId createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static BlockId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static BlockId? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get value => $_getSZ(0); - @$pb.TagNumber(1) - set value($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasValue() => $_has(0); - @$pb.TagNumber(1) - void clearValue() => clearField(1); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart deleted file mode 100644 index 4e3e1a0ecd..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart +++ /dev/null @@ -1,78 +0,0 @@ -/// -// Generated code. Do not modify. -// source: document_info.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use createBlockParamsDescriptor instead') -const CreateBlockParams$json = const { - '1': 'CreateBlockParams', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, - ], -}; - -/// Descriptor for `CreateBlockParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createBlockParamsDescriptor = $convert.base64Decode('ChFDcmVhdGVCbG9ja1BhcmFtcxIOCgJpZBgBIAEoCVICaWQSLwoJcmV2aXNpb25zGAIgASgLMhEuUmVwZWF0ZWRSZXZpc2lvblIJcmV2aXNpb25z'); -@$core.Deprecated('Use blockInfoDescriptor instead') -const BlockInfo$json = const { - '1': 'BlockInfo', - '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'text', '3': 2, '4': 1, '5': 9, '10': 'text'}, - const {'1': 'rev_id', '3': 3, '4': 1, '5': 3, '10': 'revId'}, - const {'1': 'base_rev_id', '3': 4, '4': 1, '5': 3, '10': 'baseRevId'}, - ], -}; - -/// Descriptor for `BlockInfo`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockInfoDescriptor = $convert.base64Decode('CglCbG9ja0luZm8SGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSEgoEdGV4dBgCIAEoCVIEdGV4dBIVCgZyZXZfaWQYAyABKANSBXJldklkEh4KC2Jhc2VfcmV2X2lkGAQgASgDUgliYXNlUmV2SWQ='); -@$core.Deprecated('Use resetBlockParamsDescriptor instead') -const ResetBlockParams$json = const { - '1': 'ResetBlockParams', - '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, - ], -}; - -/// Descriptor for `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', - '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'delta_str', '3': 2, '4': 1, '5': 9, '10': 'deltaStr'}, - ], -}; - -/// Descriptor for `BlockDelta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockDeltaDescriptor = $convert.base64Decode('CgpCbG9ja0RlbHRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhsKCWRlbHRhX3N0chgCIAEoCVIIZGVsdGFTdHI='); -@$core.Deprecated('Use newDocUserDescriptor instead') -const NewDocUser$json = const { - '1': 'NewDocUser', - '2': const [ - const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'}, - const {'1': 'rev_id', '3': 2, '4': 1, '5': 3, '10': 'revId'}, - const {'1': 'doc_id', '3': 3, '4': 1, '5': 9, '10': 'docId'}, - ], -}; - -/// Descriptor for `NewDocUser`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List newDocUserDescriptor = $convert.base64Decode('CgpOZXdEb2NVc2VyEhcKB3VzZXJfaWQYASABKAlSBnVzZXJJZBIVCgZyZXZfaWQYAiABKANSBXJldklkEhUKBmRvY19pZBgDIAEoCVIFZG9jSWQ='); -@$core.Deprecated('Use blockIdDescriptor instead') -const BlockId$json = const { - '1': 'BlockId', - '2': const [ - const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, - ], -}; - -/// Descriptor for `BlockId`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockIdDescriptor = $convert.base64Decode('CgdCbG9ja0lkEhQKBXZhbHVlGAEgASgJUgV2YWx1ZQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pb.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pb.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pb.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pbenum.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pbenum.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pbjson.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pbjson.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pbjson.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pbserver.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/folder_info.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/folder_info.pbserver.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/protobuf.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/protobuf.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pb.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pb.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pb.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pbenum.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pbenum.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pbjson.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pbjson.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pbserver.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/revision.pbserver.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pb.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pb.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pbenum.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pbenum.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pbjson.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pbjson.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pbserver.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/text_block_info.pbserver.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pb.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pb.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pb.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pbenum.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pbenum.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pbjson.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pbjson.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pbjson.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pbserver.dart similarity index 100% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/ws_data.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-sync/ws_data.pbserver.dart diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pb.dart new file mode 100644 index 0000000000..bcd8d6051a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pb.dart @@ -0,0 +1,137 @@ +/// +// Generated code. Do not modify. +// 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 + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'entities.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) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') + ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'exportType', $pb.PbFieldType.OE, defaultOrMaker: ExportType.Text, valueOf: ExportType.valueOf, enumValues: ExportType.values) + ..hasRequiredFields = false + ; + + ExportPayload._() : super(); + factory ExportPayload({ + $core.String? viewId, + ExportType? exportType, + }) { + final _result = create(); + if (viewId != null) { + _result.viewId = viewId; + } + if (exportType != null) { + _result.exportType = exportType; + } + return _result; + } + factory ExportPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ExportPayload.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') + ExportPayload clone() => ExportPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ExportPayload copyWith(void Function(ExportPayload) updates) => super.copyWith((message) => updates(message as ExportPayload)) as ExportPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ExportPayload create() => ExportPayload._(); + ExportPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ExportPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ExportPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get viewId => $_getSZ(0); + @$pb.TagNumber(1) + set viewId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasViewId() => $_has(0); + @$pb.TagNumber(1) + void clearViewId() => clearField(1); + + @$pb.TagNumber(2) + ExportType get exportType => $_getN(1); + @$pb.TagNumber(2) + set exportType(ExportType v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasExportType() => $_has(1); + @$pb.TagNumber(2) + void clearExportType() => clearField(2); +} + +class ExportData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ExportData', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'exportType', $pb.PbFieldType.OE, defaultOrMaker: ExportType.Text, valueOf: ExportType.valueOf, enumValues: ExportType.values) + ..hasRequiredFields = false + ; + + ExportData._() : super(); + factory ExportData({ + $core.String? data, + ExportType? exportType, + }) { + final _result = create(); + if (data != null) { + _result.data = data; + } + if (exportType != null) { + _result.exportType = exportType; + } + return _result; + } + factory ExportData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ExportData.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') + ExportData clone() => ExportData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ExportData copyWith(void Function(ExportData) updates) => super.copyWith((message) => updates(message as ExportData)) as ExportData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ExportData create() => ExportData._(); + ExportData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ExportData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ExportData? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get data => $_getSZ(0); + @$pb.TagNumber(1) + set data($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasData() => $_has(0); + @$pb.TagNumber(1) + void clearData() => clearField(1); + + @$pb.TagNumber(2) + ExportType get exportType => $_getN(1); + @$pb.TagNumber(2) + set exportType(ExportType v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasExportType() => $_has(1); + @$pb.TagNumber(2) + void clearExportType() => clearField(2); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbenum.dart new file mode 100644 index 0000000000..f5413e61f2 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbenum.dart @@ -0,0 +1,28 @@ +/// +// Generated code. Do not modify. +// 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 + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class ExportType extends $pb.ProtobufEnum { + static const ExportType Text = ExportType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Text'); + static const ExportType Markdown = ExportType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Markdown'); + static const ExportType Link = ExportType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Link'); + + static const $core.List values = [ + Text, + Markdown, + Link, + ]; + + static final $core.Map<$core.int, ExportType> _byValue = $pb.ProtobufEnum.initByValue(values); + static ExportType? valueOf($core.int value) => _byValue[value]; + + const ExportType._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbjson.dart new file mode 100644 index 0000000000..4935602b83 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbjson.dart @@ -0,0 +1,44 @@ +/// +// Generated code. Do not modify. +// 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 + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use exportTypeDescriptor instead') +const ExportType$json = const { + '1': 'ExportType', + '2': const [ + const {'1': 'Text', '2': 0}, + const {'1': 'Markdown', '2': 1}, + const {'1': 'Link', '2': 2}, + ], +}; + +/// Descriptor for `ExportType`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List exportTypeDescriptor = $convert.base64Decode('CgpFeHBvcnRUeXBlEggKBFRleHQQABIMCghNYXJrZG93bhABEggKBExpbmsQAg=='); +@$core.Deprecated('Use exportPayloadDescriptor instead') +const ExportPayload$json = const { + '1': 'ExportPayload', + '2': const [ + const {'1': 'view_id', '3': 1, '4': 1, '5': 9, '10': 'viewId'}, + const {'1': 'export_type', '3': 2, '4': 1, '5': 14, '6': '.ExportType', '10': 'exportType'}, + ], +}; + +/// Descriptor for `ExportPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List exportPayloadDescriptor = $convert.base64Decode('Cg1FeHBvcnRQYXlsb2FkEhcKB3ZpZXdfaWQYASABKAlSBnZpZXdJZBIsCgtleHBvcnRfdHlwZRgCIAEoDjILLkV4cG9ydFR5cGVSCmV4cG9ydFR5cGU='); +@$core.Deprecated('Use exportDataDescriptor instead') +const ExportData$json = const { + '1': 'ExportData', + '2': const [ + const {'1': 'data', '3': 1, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'export_type', '3': 2, '4': 1, '5': 14, '6': '.ExportType', '10': 'exportType'}, + ], +}; + +/// Descriptor for `ExportData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List exportDataDescriptor = $convert.base64Decode('CgpFeHBvcnREYXRhEhIKBGRhdGEYASABKAlSBGRhdGESLAoLZXhwb3J0X3R5cGUYAiABKA4yCy5FeHBvcnRUeXBlUgpleHBvcnRUeXBl'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbserver.dart similarity index 83% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbserver.dart index b619f42f96..88741cd6c2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbserver.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/entities.pbserver.dart @@ -1,9 +1,9 @@ /// // Generated code. Do not modify. -// source: document_info.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 'document_info.pb.dart'; +export 'entities.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pb.dart similarity index 74% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pb.dart index 4c8f36115e..5bfad20674 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pb.dart @@ -1,7 +1,11 @@ /// // Generated code. Do not modify. -// source: document_info.proto +// 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-text-block/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbenum.dart new file mode 100644 index 0000000000..d88c52395c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbenum.dart @@ -0,0 +1,28 @@ +/// +// 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 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 = [ + GetBlockData, + ApplyDelta, + 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-text-block/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbjson.dart new file mode 100644 index 0000000000..ac0f243e6f --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbjson.dart @@ -0,0 +1,22 @@ +/// +// 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': '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('CgpCbG9ja0V2ZW50EhAKDEdldEJsb2NrRGF0YRAAEg4KCkFwcGx5RGVsdGEQARISCg5FeHBvcnREb2N1bWVudBAC'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/event_map.pbserver.dart new file mode 100644 index 0000000000..e359d1146c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-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-text-block/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-block/protobuf.dart new file mode 100644 index 0000000000..a2db1d12ab --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-text-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/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 27f3e9310e..e99f1b541b 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -818,74 +818,6 @@ dependencies = [ "syn", ] -[[package]] -name = "flowy-block" -version = "0.1.0" -dependencies = [ - "async-stream", - "bytes", - "chrono", - "color-eyre", - "criterion", - "dart-notify", - "dashmap", - "derive_more", - "diesel", - "diesel_derives", - "flowy-block", - "flowy-collaboration", - "flowy-database", - "flowy-derive", - "flowy-error", - "flowy-sync", - "flowy-test", - "futures", - "futures-util", - "lib-dispatch", - "lib-infra", - "lib-ot", - "lib-ws", - "log", - "protobuf", - "rand 0.7.3", - "serde", - "serde_json", - "strum", - "strum_macros", - "tokio", - "tracing", - "unicode-segmentation", - "url", -] - -[[package]] -name = "flowy-collaboration" -version = "0.1.0" -dependencies = [ - "async-stream", - "bytes", - "chrono", - "dashmap", - "dissimilar", - "flowy-derive", - "flowy-folder-data-model", - "flowy-grid-data-model", - "futures", - "lib-infra", - "lib-ot", - "log", - "md5", - "parking_lot", - "protobuf", - "serde", - "serde_json", - "strum", - "strum_macros", - "tokio", - "tracing", - "url", -] - [[package]] name = "flowy-database" version = "0.1.0" @@ -918,10 +850,10 @@ name = "flowy-error" version = "0.1.0" dependencies = [ "bytes", - "flowy-collaboration", "flowy-database", "flowy-derive", "flowy-error-code", + "flowy-sync", "http-flowy", "lib-dispatch", "lib-infra", @@ -950,15 +882,15 @@ dependencies = [ "dart-notify", "diesel", "diesel_derives", - "flowy-block", - "flowy-collaboration", "flowy-database", "flowy-derive", "flowy-error", "flowy-folder", "flowy-folder-data-model", + "flowy-revision", "flowy-sync", "flowy-test", + "flowy-text-block", "futures", "lazy_static", "lib-dispatch", @@ -1006,12 +938,12 @@ dependencies = [ "dart-notify", "dashmap", "diesel", - "flowy-collaboration", "flowy-database", "flowy-derive", "flowy-error", "flowy-grid", "flowy-grid-data-model", + "flowy-revision", "flowy-sync", "flowy-test", "lazy_static", @@ -1056,12 +988,12 @@ dependencies = [ "bytes", "config", "dashmap", - "flowy-block", - "flowy-collaboration", "flowy-derive", "flowy-error", "flowy-folder", "flowy-folder-data-model", + "flowy-sync", + "flowy-text-block", "flowy-user", "flowy-user-data-model", "futures-util", @@ -1084,6 +1016,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "flowy-revision" +version = "0.1.0" +dependencies = [ + "async-stream", + "bytes", + "dashmap", + "diesel", + "diesel_derives", + "flowy-database", + "flowy-error", + "flowy-sync", + "futures-util", + "lib-infra", + "lib-ot", + "lib-ws", + "serde", + "strum", + "strum_macros", + "tokio", + "tracing", +] + [[package]] name = "flowy-sdk" version = "0.1.0" @@ -1092,14 +1047,14 @@ dependencies = [ "bytes", "claim 0.5.0", "color-eyre", - "flowy-block", - "flowy-collaboration", "flowy-database", "flowy-folder", "flowy-grid", "flowy-grid-data-model", "flowy-net", + "flowy-revision", "flowy-sync", + "flowy-text-block", "flowy-user", "futures-core", "futures-util", @@ -1121,21 +1076,26 @@ version = "0.1.0" dependencies = [ "async-stream", "bytes", + "chrono", "dashmap", - "diesel", - "diesel_derives", - "flowy-collaboration", - "flowy-database", - "flowy-error", - "futures-util", + "dissimilar", + "flowy-derive", + "flowy-folder-data-model", + "flowy-grid-data-model", + "futures", "lib-infra", "lib-ot", - "lib-ws", + "log", + "md5", + "parking_lot", + "protobuf", "serde", + "serde_json", "strum", "strum_macros", "tokio", "tracing", + "url", ] [[package]] @@ -1147,10 +1107,10 @@ dependencies = [ "claim 0.4.0", "claim 0.5.0", "fake", - "flowy-collaboration", "flowy-folder", "flowy-net", "flowy-sdk", + "flowy-sync", "flowy-user", "futures", "futures-util", @@ -1168,6 +1128,46 @@ dependencies = [ "tokio", ] +[[package]] +name = "flowy-text-block" +version = "0.1.0" +dependencies = [ + "async-stream", + "bytes", + "chrono", + "color-eyre", + "criterion", + "dart-notify", + "dashmap", + "derive_more", + "diesel", + "diesel_derives", + "flowy-database", + "flowy-derive", + "flowy-error", + "flowy-revision", + "flowy-sync", + "flowy-test", + "flowy-text-block", + "futures", + "futures-util", + "lib-dispatch", + "lib-infra", + "lib-ot", + "lib-ws", + "log", + "protobuf", + "rand 0.7.3", + "serde", + "serde_json", + "strum", + "strum_macros", + "tokio", + "tracing", + "unicode-segmentation", + "url", +] + [[package]] name = "flowy-user" version = "0.1.0" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 42f8187844..d4cc70df5f 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -11,9 +11,9 @@ members = [ "flowy-database", "flowy-folder", "dart-notify", - "flowy-block", + "flowy-text-block", "flowy-error", - "flowy-sync", + "flowy-revision", "flowy-grid", ] diff --git a/frontend/rust-lib/flowy-error/Cargo.toml b/frontend/rust-lib/flowy-error/Cargo.toml index b7a816b026..5041facaca 100644 --- a/frontend/rust-lib/flowy-error/Cargo.toml +++ b/frontend/rust-lib/flowy-error/Cargo.toml @@ -13,7 +13,7 @@ protobuf = {version = "2.20.0"} bytes = "1.0" -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration", optional = true} +flowy-sync = { path = "../../../shared-lib/flowy-sync", optional = true} lib-ot = { path = "../../../shared-lib/lib-ot", optional = true} serde_json = {version = "1.0", optional = true} http-flowy = { git = "https://github.com/AppFlowy-IO/AppFlowy-Server", optional = true} @@ -22,7 +22,7 @@ r2d2 = { version = "0.8", optional = true} lib-sqlite = { path = "../lib-sqlite", optional = true } [features] -collaboration = ["flowy-collaboration"] +collaboration = ["flowy-sync"] ot = ["lib-ot"] serde = ["serde_json"] http_server = ["http-flowy"] diff --git a/frontend/rust-lib/flowy-error/src/ext/collaborate.rs b/frontend/rust-lib/flowy-error/src/ext/collaborate.rs index c4a6725794..f93b2b7bc3 100644 --- a/frontend/rust-lib/flowy-error/src/ext/collaborate.rs +++ b/frontend/rust-lib/flowy-error/src/ext/collaborate.rs @@ -1,9 +1,9 @@ use crate::FlowyError; -use flowy_collaboration::errors::ErrorCode; +use flowy_sync::errors::ErrorCode; -impl std::convert::From for FlowyError { - fn from(error: flowy_collaboration::errors::CollaborateError) -> Self { +impl std::convert::From for FlowyError { + fn from(error: flowy_sync::errors::CollaborateError) -> Self { match error.code { ErrorCode::RecordNotFound => FlowyError::record_not_found().context(error.msg), _ => FlowyError::internal().context(error.msg), diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 92e7b7b535..93ff98a6f3 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -7,17 +7,17 @@ edition = "2018" [dependencies] flowy-folder-data-model = { path = "../../../shared-lib/flowy-folder-data-model" } -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } +flowy-sync = { path = "../../../shared-lib/flowy-sync" } flowy-derive = { path = "../../../shared-lib/flowy-derive" } lib-ot = { path = "../../../shared-lib/lib-ot" } lib-infra = { path = "../../../shared-lib/lib-infra" } -flowy-block = { path = "../flowy-block" } +flowy-text-block = { path = "../flowy-text-block" } flowy-database = { path = "../flowy-database" } flowy-error = { path = "../flowy-error", features = ["db", "http_server"]} dart-notify = { path = "../dart-notify" } lib-dispatch = { path = "../lib-dispatch" } -flowy-sync = { path = "../flowy-sync" } +flowy-revision = { path = "../flowy-revision" } parking_lot = "0.11" protobuf = {version = "2.18.0"} @@ -45,5 +45,5 @@ lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file [features] default = [] http_server = [] -flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-sync/flowy_unit_test"] +flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-revision/flowy_unit_test"] dart = ["lib-infra/dart", "flowy-folder/dart"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index d93dca3f4e..05847f8cc1 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -9,14 +9,14 @@ use crate::{ }, }; use bytes::Bytes; -use flowy_collaboration::client_document::default::{initial_quill_delta_string, initial_read_me}; +use flowy_sync::client_document::default::{initial_quill_delta_string, initial_read_me}; -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::disk::SQLiteTextBlockRevisionPersistence; -use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_revision::disk::SQLiteTextBlockRevisionPersistence; +use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_sync::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData}; use lazy_static::lazy_static; use lib_infra::future::FutureResult; use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc}; 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 48c83cc612..99867fb484 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -1,15 +1,15 @@ use crate::services::web_socket::make_folder_ws_manager; -use flowy_collaboration::{ +use flowy_sync::{ client_folder::{FolderChange, FolderPad}, entities::{revision::Revision, ws_data::ServerRevisionWSData}, }; use crate::manager::FolderId; use bytes::Bytes; -use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::util::make_delta_from_revisions; -use flowy_sync::{ +use flowy_revision::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, RevisionWebSocketManager, }; 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 c08a4c226e..bc8838059a 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -3,7 +3,6 @@ use crate::{ event_map::WorkspaceDatabase, services::persistence::{AppTableSql, TrashTableSql, ViewTableSql, WorkspaceTableSql}, }; -use flowy_collaboration::{client_folder::FolderPad, entities::revision::md5}; use flowy_database::kv::KV; use flowy_error::{FlowyError, FlowyResult}; use flowy_folder_data_model::entities::{ @@ -11,8 +10,9 @@ use flowy_folder_data_model::entities::{ view::{RepeatedView, View}, workspace::Workspace, }; -use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; -use flowy_sync::{RevisionLoader, RevisionPersistence}; +use flowy_revision::disk::SQLiteTextBlockRevisionPersistence; +use flowy_revision::{RevisionLoader, RevisionPersistence}; +use flowy_sync::{client_folder::FolderPad, entities::revision::md5}; use std::sync::Arc; const V1_MIGRATION: &str = "FOLDER_V1_MIGRATION"; 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 ccb35cc8ac..89b7245da9 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -7,8 +7,6 @@ use crate::{ manager::FolderId, services::{folder_editor::ClientFolderEditor, persistence::migration::FolderMigration}, }; -use flowy_collaboration::client_folder::initial_folder_delta; -use flowy_collaboration::{client_folder::FolderPad, entities::revision::Revision}; use flowy_database::ConnectionPool; use flowy_error::{FlowyError, FlowyResult}; use flowy_folder_data_model::entities::{ @@ -17,8 +15,10 @@ use flowy_folder_data_model::entities::{ view::View, workspace::Workspace, }; -use flowy_sync::disk::{RevisionRecord, RevisionState}; -use flowy_sync::mk_revision_disk_cache; +use flowy_revision::disk::{RevisionRecord, RevisionState}; +use flowy_revision::mk_revision_disk_cache; +use flowy_sync::client_folder::initial_folder_delta; +use flowy_sync::{client_folder::FolderPad, entities::revision::Revision}; use std::sync::Arc; use tokio::sync::RwLock; pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; 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 c9851d6652..185521eac3 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -13,9 +13,9 @@ use crate::{ }, }; use bytes::Bytes; -use flowy_collaboration::entities::text_block_info::TextBlockId; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::ViewDataType; +use flowy_sync::entities::text_block_info::TextBlockId; use futures::{FutureExt, StreamExt}; use lib_infra::uuid; use std::{collections::HashSet, sync::Arc}; 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 98902b8878..c14db04d3f 100644 --- a/frontend/rust-lib/flowy-folder/src/services/web_socket.rs +++ b/frontend/rust-lib/flowy-folder/src/services/web_socket.rs @@ -1,14 +1,14 @@ use crate::services::FOLDER_SYNC_INTERVAL_IN_MILLIS; use bytes::Bytes; -use flowy_collaboration::{ +use flowy_error::FlowyError; +use flowy_revision::*; +use flowy_sync::{ client_folder::FolderPad, entities::{ revision::RevisionRange, ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSDataType}, }, }; -use flowy_error::FlowyError; -use flowy_sync::*; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta}; use parking_lot::RwLock; 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 9f9bae4a82..68a1bcea65 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -2,7 +2,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTes use flowy_folder::entities::workspace::CreateWorkspacePayload; use flowy_folder_data_model::entities::view::ViewDataType; -use flowy_sync::disk::RevisionState; +use flowy_revision::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; #[tokio::test] diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index e476c36f2d..a6fd1fbe29 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -1,4 +1,3 @@ -use flowy_collaboration::entities::text_block_info::TextBlockInfo; use flowy_folder::event_map::FolderEvent::*; use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; @@ -15,8 +14,9 @@ use flowy_folder_data_model::entities::{ view::{CreateViewPayload, UpdateViewPayload}, workspace::{CreateWorkspacePayload, RepeatedWorkspace}, }; -use flowy_sync::disk::RevisionState; -use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; +use flowy_revision::disk::RevisionState; +use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; +use flowy_sync::entities::text_block_info::TextBlockInfo; use flowy_test::{event_builder::*, FlowySDKTest}; use std::{sync::Arc, time::Duration}; use tokio::time::sleep; diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 599f41c043..3549bedd08 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -8,13 +8,13 @@ edition = "2021" [dependencies] lib-dispatch = { path = "../lib-dispatch" } dart-notify = { path = "../dart-notify" } -flowy-sync = { path = "../flowy-sync" } +flowy-revision = { path = "../flowy-revision" } 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-sync = { path = "../../../shared-lib/flowy-sync" } flowy-database = { path = "../flowy-database" } strum = "0.21" @@ -45,4 +45,4 @@ lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file [features] default = [] dart = ["lib-infra/dart"] -flowy_unit_test = ["flowy-sync/flowy_unit_test"] \ No newline at end of file +flowy_unit_test = ["flowy-revision/flowy_unit_test"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index b0c1e16623..75499acdac 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -2,13 +2,13 @@ use crate::services::grid_editor::ClientGridEditor; use crate::services::kv_persistence::GridKVPersistence; use bytes::Bytes; use dashmap::DashMap; -use flowy_collaboration::client_grid::{make_block_meta_delta, make_grid_delta}; -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_database::ConnectionPool; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{BuildGridContext, GridMeta}; -use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; -use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_revision::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; +use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_sync::client_grid::{make_block_meta_delta, make_grid_delta}; +use flowy_sync::entities::revision::{RepeatedRevision, Revision}; use std::sync::Arc; use tokio::sync::RwLock; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 650b537221..ca3f99b363 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -4,17 +4,17 @@ use bytes::Bytes; use crate::dart_notification::{send_dart_notification, GridNotification}; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; -use flowy_collaboration::entities::revision::Revision; -use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RowMeta, RowMetaChangeset, RowOrder, }; -use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; -use flowy_sync::{ +use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; +use flowy_revision::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, }; +use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; +use flowy_sync::entities::revision::Revision; +use flowy_sync::util::make_delta_from_revisions; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; 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 d1276bb8ab..7bcbe39830 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,14 +1,14 @@ use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; use bytes::Bytes; -use flowy_collaboration::client_grid::{GridChangeset, GridMetaPad}; -use flowy_collaboration::entities::revision::Revision; -use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, Row, RowMeta, RowMetaChangeset, RowOrder, }; +use flowy_sync::client_grid::{GridChangeset, GridMetaPad}; +use flowy_sync::entities::revision::Revision; +use flowy_sync::util::make_delta_from_revisions; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; @@ -16,7 +16,7 @@ use crate::services::row::{ make_grid_block_from_block_metas, make_grid_blocks, make_row_meta_from_context, make_rows_from_row_metas, serialize_cell_data, CreateRowMetaBuilder, CreateRowMetaPayload, GridBlockMetaData, }; -use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; +use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 82d5399f9e..1c10eb1726 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,7 +1,7 @@ use crate::services::cell::*; use crate::services::field::*; -use flowy_collaboration::client_grid::GridBuilder; use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; +use flowy_sync::client_grid::GridBuilder; pub fn make_default_grid() -> BuildGridContext { let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index eba36d8bbd..0da0a911f1 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,5 +1,5 @@ use bytes::Bytes; -use flowy_collaboration::client_grid::GridBuilder; +use flowy_sync::client_grid::GridBuilder; use std::collections::HashMap; use flowy_grid::services::cell::*; @@ -10,7 +10,7 @@ use flowy_grid_data_model::entities::{ BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, }; -use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; +use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-net/Cargo.toml b/frontend/rust-lib/flowy-net/Cargo.toml index e494f6f5d1..b8e22e7f30 100644 --- a/frontend/rust-lib/flowy-net/Cargo.toml +++ b/frontend/rust-lib/flowy-net/Cargo.toml @@ -9,12 +9,12 @@ edition = "2018" lib-dispatch = { path = "../lib-dispatch" } flowy-error = { path = "../flowy-error", features = ["collaboration", "http_server"] } flowy-derive = { path = "../../../shared-lib/flowy-derive" } -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration"} +flowy-sync = { path = "../../../shared-lib/flowy-sync"} flowy-folder-data-model = { path = "../../../shared-lib/flowy-folder-data-model"} flowy-user-data-model = { path = "../../../shared-lib/flowy-user-data-model"} flowy-folder = { path = "../flowy-folder" } flowy-user = { path = "../flowy-user" } -flowy-block = { path = "../flowy-block" } +flowy-text-block = { path = "../flowy-text-block" } lazy_static = "1.4.0" lib-infra = { path = "../../../shared-lib/lib-infra" } protobuf = {version = "2.18.0"} @@ -43,7 +43,7 @@ http_server = [] dart = [ "lib-infra/dart", "flowy-user/dart", - "flowy-collaboration/dart", + "flowy-sync/dart", "flowy-error/dart", "flowy-user-data-model/dart", "flowy-folder-data-model/dart" 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 1016e903e4..f10c737a95 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -2,11 +2,9 @@ use crate::{ configuration::*, request::{HttpRequestBuilder, ResponseMiddleware}, }; -use flowy_block::BlockCloudService; -use flowy_collaboration::entities::text_block_info::{ - CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo, -}; use flowy_error::FlowyError; +use flowy_sync::entities::text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}; +use flowy_text_block::BlockCloudService; use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; use lib_infra::future::FutureResult; diff --git a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs index 525b487ce4..6d7dd9c342 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs @@ -1,4 +1,4 @@ -use flowy_collaboration::{ +use flowy_sync::{ entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo}, errors::CollaborateError, protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, 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 6bcd538a6b..48ead1c03d 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -1,7 +1,9 @@ use crate::local_server::persistence::LocalTextBlockCloudPersistence; use async_stream::stream; use bytes::Bytes; -use flowy_collaboration::{ +use flowy_error::{internal_error, FlowyError}; +use flowy_folder::event_map::FolderCouldServiceV1; +use flowy_sync::{ client_document::default::initial_quill_delta_string, entities::{ text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}, @@ -13,8 +15,6 @@ use flowy_collaboration::{ server_folder::ServerFolderManager, synchronizer::{RevisionSyncResponse, RevisionUser}, }; -use flowy_error::{internal_error, FlowyError}; -use flowy_folder::event_map::FolderCouldServiceV1; use futures_util::stream::StreamExt; use lib_ws::{WSChannel, WebSocketRawMessage}; use parking_lot::RwLock; @@ -251,13 +251,13 @@ impl RevisionUser for LocalRevisionUser { } } -use flowy_block::BlockCloudService; use flowy_folder_data_model::entities::{ app::{App, AppId, CreateAppParams, RepeatedApp, UpdateAppParams}, trash::{RepeatedTrash, RepeatedTrashId}, view::{CreateViewParams, RepeatedView, RepeatedViewId, UpdateViewParams, View, ViewId}, workspace::{CreateWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams, Workspace, WorkspaceId}, }; +use flowy_text_block::BlockCloudService; use flowy_user::event_map::UserCloudService; use flowy_user_data_model::entities::{ SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile, diff --git a/frontend/rust-lib/flowy-sync/Cargo.toml b/frontend/rust-lib/flowy-revision/Cargo.toml similarity index 86% rename from frontend/rust-lib/flowy-sync/Cargo.toml rename to frontend/rust-lib/flowy-revision/Cargo.toml index 42e43826ba..504e05a2ce 100644 --- a/frontend/rust-lib/flowy-sync/Cargo.toml +++ b/frontend/rust-lib/flowy-revision/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "flowy-sync" +name = "flowy-revision" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } +flowy-sync = { path = "../../../shared-lib/flowy-sync" } lib-ot = { path = "../../../shared-lib/lib-ot" } lib-ws = { path = "../../../shared-lib/lib-ws" } lib-infra = { path = "../../../shared-lib/lib-infra" } diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs b/frontend/rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs similarity index 100% rename from frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs rename to frontend/rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs b/frontend/rust-lib/flowy-revision/src/cache/disk/grid_meta_rev_impl.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs rename to frontend/rust-lib/flowy-revision/src/cache/disk/grid_meta_rev_impl.rs index 4cd46058bf..e850119c30 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs +++ b/frontend/rust-lib/flowy-revision/src/cache/disk/grid_meta_rev_impl.rs @@ -3,10 +3,6 @@ use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; -use flowy_collaboration::{ - entities::revision::{Revision, RevisionRange}, - util::md5, -}; use flowy_database::{ impl_sql_integer_expression, insert_or_ignore_into, prelude::*, @@ -14,6 +10,10 @@ use flowy_database::{ ConnectionPool, }; use flowy_error::{internal_error, FlowyError, FlowyResult}; +use flowy_sync::{ + entities::revision::{Revision, RevisionRange}, + util::md5, +}; use std::sync::Arc; pub struct SQLiteGridBlockMetaRevisionPersistence { diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-revision/src/cache/disk/grid_rev_impl.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs rename to frontend/rust-lib/flowy-revision/src/cache/disk/grid_rev_impl.rs index 414bbb96c9..d51ea8e48c 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-revision/src/cache/disk/grid_rev_impl.rs @@ -3,10 +3,6 @@ use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; -use flowy_collaboration::{ - entities::revision::{Revision, RevisionRange}, - util::md5, -}; use flowy_database::{ impl_sql_integer_expression, insert_or_ignore_into, prelude::*, @@ -14,6 +10,10 @@ use flowy_database::{ ConnectionPool, }; use flowy_error::{internal_error, FlowyError, FlowyResult}; +use flowy_sync::{ + entities::revision::{Revision, RevisionRange}, + util::md5, +}; use std::sync::Arc; pub struct SQLiteGridRevisionPersistence { diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-revision/src/cache/disk/mod.rs similarity index 96% rename from frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs rename to frontend/rust-lib/flowy-revision/src/cache/disk/mod.rs index 3a278afe36..945c6d707f 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-revision/src/cache/disk/mod.rs @@ -8,8 +8,8 @@ pub use grid_meta_rev_impl::*; pub use grid_rev_impl::*; pub use text_rev_impl::*; -use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; +use flowy_sync::entities::revision::{RevId, Revision, RevisionRange}; use std::fmt::Debug; pub trait RevisionDiskCache: Sync + Send { diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs b/frontend/rust-lib/flowy-revision/src/cache/disk/text_rev_impl.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs rename to frontend/rust-lib/flowy-revision/src/cache/disk/text_rev_impl.rs index 13a8298916..165864d5db 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs +++ b/frontend/rust-lib/flowy-revision/src/cache/disk/text_rev_impl.rs @@ -3,10 +3,6 @@ use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; -use flowy_collaboration::{ - entities::revision::{RevType, Revision, RevisionRange}, - util::md5, -}; use flowy_database::{ impl_sql_integer_expression, insert_or_ignore_into, prelude::*, @@ -14,6 +10,10 @@ use flowy_database::{ ConnectionPool, }; use flowy_error::{internal_error, FlowyError, FlowyResult}; +use flowy_sync::{ + entities::revision::{RevType, Revision, RevisionRange}, + util::md5, +}; use std::sync::Arc; pub struct SQLiteTextBlockRevisionPersistence { diff --git a/frontend/rust-lib/flowy-sync/src/cache/memory.rs b/frontend/rust-lib/flowy-revision/src/cache/memory.rs similarity index 98% rename from frontend/rust-lib/flowy-sync/src/cache/memory.rs rename to frontend/rust-lib/flowy-revision/src/cache/memory.rs index f709abcdd2..6120c3f224 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/memory.rs +++ b/frontend/rust-lib/flowy-revision/src/cache/memory.rs @@ -1,8 +1,8 @@ use crate::disk::RevisionRecord; use crate::REVISION_WRITE_INTERVAL_IN_MILLIS; use dashmap::DashMap; -use flowy_collaboration::entities::revision::RevisionRange; use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::entities::revision::RevisionRange; use std::{borrow::Cow, sync::Arc, time::Duration}; use tokio::{sync::RwLock, task::JoinHandle}; diff --git a/frontend/rust-lib/flowy-sync/src/cache/mod.rs b/frontend/rust-lib/flowy-revision/src/cache/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-sync/src/cache/mod.rs rename to frontend/rust-lib/flowy-revision/src/cache/mod.rs diff --git a/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs b/frontend/rust-lib/flowy-revision/src/conflict_resolve.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/conflict_resolve.rs rename to frontend/rust-lib/flowy-revision/src/conflict_resolve.rs index a4f4f6c818..0a63f37f3e 100644 --- a/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs +++ b/frontend/rust-lib/flowy-revision/src/conflict_resolve.rs @@ -1,13 +1,13 @@ use crate::RevisionManager; use bytes::Bytes; -use flowy_collaboration::{ +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::{ entities::{ revision::{RepeatedRevision, Revision, RevisionRange}, ws_data::ServerRevisionWSDataType, }, util::make_delta_from_revisions, }; -use flowy_error::{FlowyError, FlowyResult}; use lib_infra::future::BoxResultFuture; use lib_ot::core::{Attributes, Delta, PlainTextAttributes}; use lib_ot::rich_text::RichTextAttributes; diff --git a/frontend/rust-lib/flowy-sync/src/lib.rs b/frontend/rust-lib/flowy-revision/src/lib.rs similarity index 100% rename from frontend/rust-lib/flowy-sync/src/lib.rs rename to frontend/rust-lib/flowy-revision/src/lib.rs diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-revision/src/rev_manager.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/rev_manager.rs rename to frontend/rust-lib/flowy-revision/src/rev_manager.rs index 7b34bb8115..3cd9b54de0 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-revision/src/rev_manager.rs @@ -1,11 +1,11 @@ use crate::disk::RevisionState; use crate::{RevisionPersistence, WSDataProviderDataSource}; use bytes::Bytes; -use flowy_collaboration::{ +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::{ entities::revision::{RepeatedRevision, Revision, RevisionRange}, util::{pair_rev_id_from_revisions, RevIdCounter}, }; -use flowy_error::{FlowyError, FlowyResult}; use lib_infra::future::FutureResult; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-revision/src/rev_persistence.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/rev_persistence.rs rename to frontend/rust-lib/flowy-revision/src/rev_persistence.rs index 8a1d9647c4..6412b26ec6 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-revision/src/rev_persistence.rs @@ -5,9 +5,9 @@ use crate::cache::{ use crate::disk::{RevisionRecord, RevisionState}; use crate::memory::RevisionMemoryCache; use crate::RevisionCompactor; -use flowy_collaboration::entities::revision::{Revision, RevisionRange}; use flowy_database::ConnectionPool; use flowy_error::{internal_error, FlowyError, FlowyResult}; +use flowy_sync::entities::revision::{Revision, RevisionRange}; use std::collections::VecDeque; use std::{borrow::Cow, sync::Arc}; use tokio::sync::RwLock; diff --git a/frontend/rust-lib/flowy-sync/src/ws_manager.rs b/frontend/rust-lib/flowy-revision/src/ws_manager.rs similarity index 99% rename from frontend/rust-lib/flowy-sync/src/ws_manager.rs rename to frontend/rust-lib/flowy-revision/src/ws_manager.rs index 1a5891dbbb..42ad39c617 100644 --- a/frontend/rust-lib/flowy-sync/src/ws_manager.rs +++ b/frontend/rust-lib/flowy-revision/src/ws_manager.rs @@ -2,11 +2,11 @@ use crate::ConflictRevisionSink; use async_stream::stream; use bytes::Bytes; -use flowy_collaboration::entities::{ +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::entities::{ revision::{RevId, Revision, RevisionRange}, ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSData, ServerRevisionWSDataType}, }; -use flowy_error::{FlowyError, FlowyResult}; use futures_util::{future::BoxFuture, stream::StreamExt}; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ws::WSConnectState; diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 75ab8a3b5c..9ac3bef2f6 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -14,8 +14,8 @@ flowy-folder = { path = "../flowy-folder", default-features = false } flowy-grid = { path = "../flowy-grid", default-features = false } flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } flowy-database = { path = "../flowy-database" } -flowy-block = { path = "../flowy-block", default-features = false } -flowy-sync = { path = "../flowy-sync" } +flowy-text-block = { path = "../flowy-text-block", default-features = false } +flowy-revision = { path = "../flowy-revision" } tracing = { version = "0.1" } log = "0.4.14" @@ -25,7 +25,7 @@ bytes = "1.0" tokio = { version = "1", features = ["rt"] } parking_lot = "0.11" -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } +flowy-sync = { path = "../../../shared-lib/flowy-sync" } lib-ws = { path = "../../../shared-lib/lib-ws" } lib-infra = { path = "../../../shared-lib/lib-infra" } @@ -38,6 +38,6 @@ tokio = { version = "1", features = ["full"]} futures-util = "0.3.15" [features] -http_server = ["flowy-user/http_server", "flowy-folder/http_server", "flowy-block/http_server"] +http_server = ["flowy-user/http_server", "flowy-folder/http_server", "flowy-text-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", "flowy-block/dart"] +dart = ["flowy-user/dart", "flowy-net/dart", "flowy-folder/dart", "flowy-sync/dart", "flowy-grid/dart", "flowy-text-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 6ed3df3207..24af171a92 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,9 +1,9 @@ use bytes::Bytes; -use flowy_block::TextBlockManager; -use flowy_collaboration::client_document::default::initial_quill_delta_string; -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; -use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; +use flowy_sync::client_document::default::initial_quill_delta_string; +use flowy_sync::entities::revision::{RepeatedRevision, Revision}; +use flowy_sync::entities::ws_data::ClientRevisionWSData; +use flowy_text_block::TextBlockManager; use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; use flowy_folder::prelude::ViewDataType; @@ -19,7 +19,7 @@ use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, }; -use flowy_sync::{RevisionWebSocket, WSStateReceiver}; +use flowy_revision::{RevisionWebSocket, WSStateReceiver}; use flowy_user::services::UserSession; use futures_core::future::BoxFuture; use lib_infra::future::{BoxResultFuture, FutureResult}; 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 64ad6e9dd4..514c320511 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 @@ -1,10 +1,10 @@ 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_revision::{RevisionWebSocket, WSStateReceiver}; +use flowy_sync::entities::ws_data::ClientRevisionWSData; use flowy_user::services::UserSession; use futures_core::future::BoxFuture; use lib_infra::future::BoxResultFuture; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs index 5482bbe546..7b80e637ab 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs @@ -1,15 +1,15 @@ use bytes::Bytes; -use flowy_block::{ - errors::{internal_error, FlowyError}, - BlockCloudService, TextBlockManager, TextBlockUser, -}; -use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::document::BlockHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, }; -use flowy_sync::{RevisionWebSocket, WSStateReceiver}; +use flowy_revision::{RevisionWebSocket, WSStateReceiver}; +use flowy_sync::entities::ws_data::ClientRevisionWSData; +use flowy_text_block::{ + errors::{internal_error, FlowyError}, + BlockCloudService, TextBlockManager, TextBlockUser, +}; use flowy_user::services::UserSession; use futures_core::future::BoxFuture; use lib_infra::future::BoxResultFuture; diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 7acf14952e..8ade107e00 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -3,7 +3,6 @@ pub mod module; pub use flowy_net::get_client_server_configuration; use crate::deps_resolve::*; -use flowy_block::TextBlockManager; use flowy_folder::{errors::FlowyError, manager::FolderManager}; use flowy_grid::manager::GridManager; use flowy_net::ClientServerConfiguration; @@ -12,6 +11,7 @@ use flowy_net::{ local_server::LocalServer, ws::connection::{listen_on_websocket, FlowyWebSocketConnect}, }; +use flowy_text_block::TextBlockManager; use flowy_user::services::{notifier::UserStatus, UserSession, UserSessionConfig}; use lib_dispatch::prelude::*; use lib_dispatch::util::tokio_default_runtime; diff --git a/frontend/rust-lib/flowy-sdk/src/module.rs b/frontend/rust-lib/flowy-sdk/src/module.rs index 0a3fb1f87a..cbb1673a17 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -1,7 +1,7 @@ -use flowy_block::TextBlockManager; use flowy_folder::manager::FolderManager; use flowy_grid::manager::GridManager; use flowy_net::ws::connection::FlowyWebSocketConnect; +use flowy_text_block::TextBlockManager; use flowy_user::services::UserSession; use lib_dispatch::prelude::Module; use std::sync::Arc; @@ -44,5 +44,5 @@ fn mk_grid_module(grid_manager: Arc) -> Module { } fn mk_text_block_module(text_block_manager: Arc) -> Module { - flowy_block::event_map::create(text_block_manager) + flowy_text_block::event_map::create(text_block_manager) } diff --git a/frontend/rust-lib/flowy-test/Cargo.toml b/frontend/rust-lib/flowy-test/Cargo.toml index 0a04c1d5f6..4499a34828 100644 --- a/frontend/rust-lib/flowy-test/Cargo.toml +++ b/frontend/rust-lib/flowy-test/Cargo.toml @@ -12,7 +12,7 @@ flowy-net = { path = "../flowy-net"} flowy-folder = { path = "../flowy-folder", default-features = false} lib-dispatch = { path = "../lib-dispatch" } -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } +flowy-sync = { path = "../../../shared-lib/flowy-sync" } lib-ot = { path = "../../../shared-lib/lib-ot" } lib-infra = { path = "../../../shared-lib/lib-infra" } diff --git a/frontend/rust-lib/flowy-block/Cargo.toml b/frontend/rust-lib/flowy-text-block/Cargo.toml similarity index 82% rename from frontend/rust-lib/flowy-block/Cargo.toml rename to frontend/rust-lib/flowy-text-block/Cargo.toml index b4ae85f597..84c0cf9605 100644 --- a/frontend/rust-lib/flowy-block/Cargo.toml +++ b/frontend/rust-lib/flowy-text-block/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "flowy-block" +name = "flowy-text-block" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration"} +flowy-sync = { path = "../../../shared-lib/flowy-sync"} flowy-derive = { path = "../../../shared-lib/flowy-derive" } lib-ot = { path = "../../../shared-lib/lib-ot" } lib-ws = { path = "../../../shared-lib/lib-ws" } @@ -15,7 +15,7 @@ lib-infra = { path = "../../../shared-lib/lib-infra" } lib-dispatch = { path = "../lib-dispatch" } flowy-database = { path = "../flowy-database" } -flowy-sync = { path = "../flowy-sync" } +flowy-revision = { path = "../flowy-revision" } flowy-error = { path = "../flowy-error", features = ["collaboration", "ot", "http_server", "serde", "db"] } dart-notify = { path = "../dart-notify" } @@ -40,7 +40,7 @@ futures = "0.3.15" [dev-dependencies] flowy-test = { path = "../flowy-test" } -flowy-block = { path = "../flowy-block", features = ["flowy_unit_test"]} +flowy-text-block = { path = "../flowy-text-block", features = ["flowy_unit_test"]} derive_more = {version = "0.99", features = ["display"]} color-eyre = { version = "0.5", default-features = false } @@ -52,5 +52,5 @@ lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file [features] http_server = [] -flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-sync/flowy_unit_test"] +flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-revision/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-text-block/Flowy.toml similarity index 100% rename from frontend/rust-lib/flowy-block/Flowy.toml rename to frontend/rust-lib/flowy-text-block/Flowy.toml diff --git a/frontend/rust-lib/flowy-block/build.rs b/frontend/rust-lib/flowy-text-block/build.rs similarity index 100% rename from frontend/rust-lib/flowy-block/build.rs rename to frontend/rust-lib/flowy-text-block/build.rs diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-text-block/src/editor.rs similarity index 98% rename from frontend/rust-lib/flowy-block/src/editor.rs rename to frontend/rust-lib/flowy-text-block/src/editor.rs index 8622c60730..215c3d079d 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-text-block/src/editor.rs @@ -5,16 +5,16 @@ use crate::{ TextBlockUser, }; use bytes::Bytes; -use flowy_collaboration::entities::ws_data::ServerRevisionWSData; -use flowy_collaboration::{ +use flowy_error::{internal_error, FlowyResult}; +use flowy_revision::{ + RevisionCloudService, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, RevisionWebSocketManager, +}; +use flowy_sync::entities::ws_data::ServerRevisionWSData; +use flowy_sync::{ entities::{revision::Revision, text_block_info::TextBlockInfo}, errors::CollaborateResult, util::make_delta_from_revisions, }; -use flowy_error::{internal_error, FlowyResult}; -use flowy_sync::{ - RevisionCloudService, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, RevisionWebSocketManager, -}; use lib_ot::{ core::{Interval, Operation}, rich_text::{RichTextAttribute, RichTextDelta}, diff --git a/frontend/rust-lib/flowy-block/src/entities.rs b/frontend/rust-lib/flowy-text-block/src/entities.rs similarity index 100% rename from frontend/rust-lib/flowy-block/src/entities.rs rename to frontend/rust-lib/flowy-text-block/src/entities.rs diff --git a/frontend/rust-lib/flowy-block/src/event_handler.rs b/frontend/rust-lib/flowy-text-block/src/event_handler.rs similarity index 94% rename from frontend/rust-lib/flowy-block/src/event_handler.rs rename to frontend/rust-lib/flowy-text-block/src/event_handler.rs index 1457fc2992..4e8b48ae05 100644 --- a/frontend/rust-lib/flowy-block/src/event_handler.rs +++ b/frontend/rust-lib/flowy-text-block/src/event_handler.rs @@ -1,7 +1,7 @@ use crate::entities::{ExportData, ExportParams, ExportPayload}; use crate::TextBlockManager; -use flowy_collaboration::entities::text_block_info::{TextBlockDelta, TextBlockId}; use flowy_error::FlowyError; +use flowy_sync::entities::text_block_info::{TextBlockDelta, TextBlockId}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::convert::TryInto; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-block/src/event_map.rs b/frontend/rust-lib/flowy-text-block/src/event_map.rs similarity index 86% rename from frontend/rust-lib/flowy-block/src/event_map.rs rename to frontend/rust-lib/flowy-text-block/src/event_map.rs index 8342102bf5..a355af8bc3 100644 --- a/frontend/rust-lib/flowy-block/src/event_map.rs +++ b/frontend/rust-lib/flowy-text-block/src/event_map.rs @@ -19,10 +19,10 @@ 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")] + #[event(input = "TextBlockId", output = "TextBlockDelta")] GetBlockData = 0, - #[event(input = "BlockDelta", output = "BlockDelta")] + #[event(input = "TextBlockDelta", output = "TextBlockDelta")] ApplyDelta = 1, #[event(input = "ExportPayload", output = "ExportData")] diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-text-block/src/lib.rs similarity index 84% rename from frontend/rust-lib/flowy-block/src/lib.rs rename to frontend/rust-lib/flowy-text-block/src/lib.rs index b3c9de44dc..991fed8f38 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-text-block/src/lib.rs @@ -15,9 +15,7 @@ pub mod errors { pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; use crate::errors::FlowyError; -use flowy_collaboration::entities::text_block_info::{ - CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo, -}; +use flowy_sync::entities::text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}; use lib_infra::future::FutureResult; pub trait BlockCloudService: Send + Sync { diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-text-block/src/manager.rs similarity index 97% rename from frontend/rust-lib/flowy-block/src/manager.rs rename to frontend/rust-lib/flowy-text-block/src/manager.rs index a08dc9b7b1..a79f5cb3f4 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-text-block/src/manager.rs @@ -1,15 +1,15 @@ use crate::{editor::ClientTextBlockEditor, errors::FlowyError, BlockCloudService}; use bytes::Bytes; use dashmap::DashMap; -use flowy_collaboration::entities::{ +use flowy_database::ConnectionPool; +use flowy_error::FlowyResult; +use flowy_revision::disk::SQLiteTextBlockRevisionPersistence; +use flowy_revision::{RevisionCloudService, RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_sync::entities::{ revision::{md5, RepeatedRevision, Revision}, text_block_info::{TextBlockDelta, TextBlockId}, ws_data::ServerRevisionWSData, }; -use flowy_database::ConnectionPool; -use flowy_error::FlowyResult; -use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; -use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_infra::future::FutureResult; use std::{convert::TryInto, sync::Arc}; diff --git a/frontend/rust-lib/flowy-block/src/protobuf/mod.rs b/frontend/rust-lib/flowy-text-block/src/protobuf/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-block/src/protobuf/mod.rs rename to frontend/rust-lib/flowy-text-block/src/protobuf/mod.rs diff --git a/frontend/rust-lib/flowy-block/src/protobuf/model/entities.rs b/frontend/rust-lib/flowy-text-block/src/protobuf/model/entities.rs similarity index 100% rename from frontend/rust-lib/flowy-block/src/protobuf/model/entities.rs rename to frontend/rust-lib/flowy-text-block/src/protobuf/model/entities.rs diff --git a/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-text-block/src/protobuf/model/event_map.rs similarity index 100% rename from frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs rename to frontend/rust-lib/flowy-text-block/src/protobuf/model/event_map.rs diff --git a/frontend/rust-lib/flowy-block/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-text-block/src/protobuf/model/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-block/src/protobuf/model/mod.rs rename to frontend/rust-lib/flowy-text-block/src/protobuf/model/mod.rs diff --git a/frontend/rust-lib/flowy-block/src/protobuf/proto/entities.proto b/frontend/rust-lib/flowy-text-block/src/protobuf/proto/entities.proto similarity index 100% rename from frontend/rust-lib/flowy-block/src/protobuf/proto/entities.proto rename to frontend/rust-lib/flowy-text-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-text-block/src/protobuf/proto/event_map.proto similarity index 100% rename from frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto rename to frontend/rust-lib/flowy-text-block/src/protobuf/proto/event_map.proto diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-text-block/src/queue.rs similarity index 98% rename from frontend/rust-lib/flowy-block/src/queue.rs rename to frontend/rust-lib/flowy-text-block/src/queue.rs index f7932e0850..7c11afd0ff 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-text-block/src/queue.rs @@ -2,14 +2,14 @@ use crate::web_socket::EditorCommandReceiver; use crate::TextBlockUser; use async_stream::stream; use bytes::Bytes; -use flowy_collaboration::util::make_delta_from_revisions; -use flowy_collaboration::{ +use flowy_error::{FlowyError, FlowyResult}; +use flowy_revision::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas}; +use flowy_sync::util::make_delta_from_revisions; +use flowy_sync::{ client_document::{history::UndoResult, ClientDocument}, entities::revision::{RevId, Revision}, errors::CollaborateError, }; -use flowy_error::{FlowyError, FlowyResult}; -use flowy_sync::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas}; use futures::stream::StreamExt; use lib_ot::{ core::{Interval, OperationTransformable}, diff --git a/frontend/rust-lib/flowy-block/src/web_socket.rs b/frontend/rust-lib/flowy-text-block/src/web_socket.rs similarity index 97% rename from frontend/rust-lib/flowy-block/src/web_socket.rs rename to frontend/rust-lib/flowy-text-block/src/web_socket.rs index 7450e4a6ae..8854acfd9f 100644 --- a/frontend/rust-lib/flowy-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-text-block/src/web_socket.rs @@ -1,14 +1,14 @@ use crate::{queue::EditorCommand, TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS}; use bytes::Bytes; -use flowy_collaboration::{ +use flowy_error::{internal_error, FlowyError}; +use flowy_revision::*; +use flowy_sync::{ entities::{ revision::RevisionRange, ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSDataType}, }, errors::CollaborateResult, }; -use flowy_error::{internal_error, FlowyError}; -use flowy_sync::*; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ot::rich_text::RichTextAttributes; use lib_ot::rich_text::RichTextDelta; @@ -129,7 +129,7 @@ impl ConflictResolver for TextBlockConflictResolver { fn transform_delta( &self, delta: RichTextDelta, - ) -> BoxResultFuture { + ) -> BoxResultFuture { let tx = self.edit_cmd_tx.clone(); Box::pin(async move { let (ret, rx) = oneshot::channel::>(); diff --git a/frontend/rust-lib/flowy-block/tests/document/mod.rs b/frontend/rust-lib/flowy-text-block/tests/document/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-block/tests/document/mod.rs rename to frontend/rust-lib/flowy-text-block/tests/document/mod.rs diff --git a/frontend/rust-lib/flowy-block/tests/document/script.rs b/frontend/rust-lib/flowy-text-block/tests/document/script.rs similarity index 95% rename from frontend/rust-lib/flowy-block/tests/document/script.rs rename to frontend/rust-lib/flowy-text-block/tests/document/script.rs index 2ae6e14fc9..5511896fc2 100644 --- a/frontend/rust-lib/flowy-block/tests/document/script.rs +++ b/frontend/rust-lib/flowy-text-block/tests/document/script.rs @@ -1,7 +1,7 @@ -use flowy_block::editor::ClientTextBlockEditor; -use flowy_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS; -use flowy_sync::disk::RevisionState; +use flowy_revision::disk::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; +use flowy_text_block::editor::ClientTextBlockEditor; +use flowy_text_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS; use lib_ot::{core::Interval, rich_text::RichTextDelta}; use std::sync::Arc; use tokio::time::{sleep, Duration}; diff --git a/frontend/rust-lib/flowy-block/tests/document/text_block_test.rs b/frontend/rust-lib/flowy-text-block/tests/document/text_block_test.rs similarity index 98% rename from frontend/rust-lib/flowy-block/tests/document/text_block_test.rs rename to frontend/rust-lib/flowy-text-block/tests/document/text_block_test.rs index 93fb957cdb..30a926c3f9 100644 --- a/frontend/rust-lib/flowy-block/tests/document/text_block_test.rs +++ b/frontend/rust-lib/flowy-text-block/tests/document/text_block_test.rs @@ -1,5 +1,5 @@ use crate::document::script::{EditorScript::*, *}; -use flowy_sync::disk::RevisionState; +use flowy_revision::disk::RevisionState; use lib_ot::core::{count_utf16_code_units, Interval}; #[tokio::test] diff --git a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs b/frontend/rust-lib/flowy-text-block/tests/editor/attribute_test.rs similarity index 99% rename from frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs rename to frontend/rust-lib/flowy-text-block/tests/editor/attribute_test.rs index 264cee831b..037b36970b 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/attribute_test.rs @@ -1,6 +1,6 @@ #![cfg_attr(rustfmt, rustfmt::skip)] use crate::editor::{TestBuilder, TestOp::*}; -use flowy_collaboration::client_document::{NewlineDoc, PlainDoc}; +use flowy_sync::client_document::{NewlineDoc, PlainDoc}; use lib_ot::core::{Interval, OperationTransformable, NEW_LINE, WHITESPACE, FlowyStr}; use unicode_segmentation::UnicodeSegmentation; use lib_ot::rich_text::RichTextDelta; diff --git a/frontend/rust-lib/flowy-block/tests/editor/mod.rs b/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs similarity index 99% rename from frontend/rust-lib/flowy-block/tests/editor/mod.rs rename to frontend/rust-lib/flowy-text-block/tests/editor/mod.rs index 395629587e..d1c6f94380 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/mod.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs @@ -4,7 +4,7 @@ mod op_test; mod serde_test; mod undo_redo_test; -use flowy_collaboration::client_document::{ClientDocument, InitialDocumentText}; +use flowy_sync::client_document::{ClientDocument, InitialDocumentText}; use lib_ot::{ core::*, rich_text::{RichTextAttribute, RichTextAttributes, RichTextDelta}, diff --git a/frontend/rust-lib/flowy-block/tests/editor/op_test.rs b/frontend/rust-lib/flowy-text-block/tests/editor/op_test.rs similarity index 99% rename from frontend/rust-lib/flowy-block/tests/editor/op_test.rs rename to frontend/rust-lib/flowy-text-block/tests/editor/op_test.rs index 7745d4b098..3f174fa3bc 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/op_test.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/op_test.rs @@ -1,6 +1,6 @@ #![allow(clippy::all)] use crate::editor::{Rng, TestBuilder, TestOp::*}; -use flowy_collaboration::client_document::{NewlineDoc, PlainDoc}; +use flowy_sync::client_document::{NewlineDoc, PlainDoc}; use lib_ot::{ core::*, rich_text::{AttributeBuilder, RichTextAttribute, RichTextAttributes, RichTextDelta}, diff --git a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs b/frontend/rust-lib/flowy-text-block/tests/editor/serde_test.rs similarity index 98% rename from frontend/rust-lib/flowy-block/tests/editor/serde_test.rs rename to frontend/rust-lib/flowy-text-block/tests/editor/serde_test.rs index 54c7f92152..87d425901b 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/serde_test.rs @@ -1,4 +1,4 @@ -use flowy_collaboration::client_document::{ClientDocument, PlainDoc}; +use flowy_sync::client_document::{ClientDocument, PlainDoc}; use lib_ot::rich_text::RichTextOperation; use lib_ot::{ core::*, diff --git a/frontend/rust-lib/flowy-block/tests/editor/undo_redo_test.rs b/frontend/rust-lib/flowy-text-block/tests/editor/undo_redo_test.rs similarity index 99% rename from frontend/rust-lib/flowy-block/tests/editor/undo_redo_test.rs rename to frontend/rust-lib/flowy-text-block/tests/editor/undo_redo_test.rs index 1b08b5ca2d..e6ea9200ab 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/undo_redo_test.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/undo_redo_test.rs @@ -1,5 +1,5 @@ use crate::editor::{TestBuilder, TestOp::*}; -use flowy_collaboration::client_document::{NewlineDoc, PlainDoc, RECORD_THRESHOLD}; +use flowy_sync::client_document::{NewlineDoc, PlainDoc, RECORD_THRESHOLD}; use lib_ot::core::{Interval, NEW_LINE, WHITESPACE}; #[test] diff --git a/frontend/rust-lib/flowy-block/tests/main.rs b/frontend/rust-lib/flowy-text-block/tests/main.rs similarity index 100% rename from frontend/rust-lib/flowy-block/tests/main.rs rename to frontend/rust-lib/flowy-text-block/tests/main.rs diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index a4cde5ddf2..db2a3d9ad7 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -402,34 +402,6 @@ dependencies = [ "syn", ] -[[package]] -name = "flowy-collaboration" -version = "0.1.0" -dependencies = [ - "async-stream", - "bytes", - "chrono", - "dashmap", - "dissimilar", - "flowy-derive", - "flowy-folder-data-model", - "flowy-grid-data-model", - "futures", - "lib-infra", - "lib-ot", - "log", - "md5", - "parking_lot", - "protobuf", - "serde", - "serde_json", - "strum", - "strum_macros", - "tokio", - "tracing", - "url", -] - [[package]] name = "flowy-derive" version = "0.1.0" @@ -495,6 +467,34 @@ dependencies = [ "uuid", ] +[[package]] +name = "flowy-sync" +version = "0.1.0" +dependencies = [ + "async-stream", + "bytes", + "chrono", + "dashmap", + "dissimilar", + "flowy-derive", + "flowy-folder-data-model", + "flowy-grid-data-model", + "futures", + "lib-infra", + "lib-ot", + "log", + "md5", + "parking_lot", + "protobuf", + "serde", + "serde_json", + "strum", + "strum_macros", + "tokio", + "tracing", + "url", +] + [[package]] name = "flowy-user-data-model" version = "0.1.0" diff --git a/shared-lib/Cargo.toml b/shared-lib/Cargo.toml index 3dca4e2f6d..370c4d7f31 100644 --- a/shared-lib/Cargo.toml +++ b/shared-lib/Cargo.toml @@ -2,7 +2,7 @@ members = [ "flowy-user-data-model", "flowy-folder-data-model", - "flowy-collaboration", + "flowy-sync", "lib-ot", "lib-ws", "lib-infra", diff --git a/shared-lib/flowy-collaboration/Cargo.toml b/shared-lib/flowy-sync/Cargo.toml similarity index 94% rename from shared-lib/flowy-collaboration/Cargo.toml rename to shared-lib/flowy-sync/Cargo.toml index 4e36f0832b..6c66a21999 100644 --- a/shared-lib/flowy-collaboration/Cargo.toml +++ b/shared-lib/flowy-sync/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "flowy-collaboration" +name = "flowy-sync" version = "0.1.0" edition = "2018" diff --git a/shared-lib/flowy-collaboration/Flowy.toml b/shared-lib/flowy-sync/Flowy.toml similarity index 100% rename from shared-lib/flowy-collaboration/Flowy.toml rename to shared-lib/flowy-sync/Flowy.toml diff --git a/shared-lib/flowy-collaboration/build.rs b/shared-lib/flowy-sync/build.rs similarity index 100% rename from shared-lib/flowy-collaboration/build.rs rename to shared-lib/flowy-sync/build.rs diff --git a/shared-lib/flowy-collaboration/src/READ_ME.json b/shared-lib/flowy-sync/src/READ_ME.json similarity index 100% rename from shared-lib/flowy-collaboration/src/READ_ME.json rename to shared-lib/flowy-sync/src/READ_ME.json diff --git a/shared-lib/flowy-collaboration/src/client_document/data.rs b/shared-lib/flowy-sync/src/client_document/data.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/data.rs rename to shared-lib/flowy-sync/src/client_document/data.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/default/READ_ME.json b/shared-lib/flowy-sync/src/client_document/default/READ_ME.json similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/default/READ_ME.json rename to shared-lib/flowy-sync/src/client_document/default/READ_ME.json diff --git a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs b/shared-lib/flowy-sync/src/client_document/default/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/default/mod.rs rename to shared-lib/flowy-sync/src/client_document/default/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs b/shared-lib/flowy-sync/src/client_document/document_pad.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/document_pad.rs rename to shared-lib/flowy-sync/src/client_document/document_pad.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/delete/default_delete.rs b/shared-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/delete/default_delete.rs rename to shared-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/delete/mod.rs b/shared-lib/flowy-sync/src/client_document/extensions/delete/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/delete/mod.rs rename to shared-lib/flowy-sync/src/client_document/extensions/delete/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/delete/preserve_line_format_merge.rs b/shared-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/delete/preserve_line_format_merge.rs rename to shared-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/format/format_at_position.rs b/shared-lib/flowy-sync/src/client_document/extensions/format/format_at_position.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/format/format_at_position.rs rename to shared-lib/flowy-sync/src/client_document/extensions/format/format_at_position.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/format/mod.rs b/shared-lib/flowy-sync/src/client_document/extensions/format/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/format/mod.rs rename to shared-lib/flowy-sync/src/client_document/extensions/format/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/format/resolve_block_format.rs b/shared-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/format/resolve_block_format.rs rename to shared-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/format/resolve_inline_format.rs b/shared-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/format/resolve_inline_format.rs rename to shared-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/helper.rs b/shared-lib/flowy-sync/src/client_document/extensions/helper.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/helper.rs rename to shared-lib/flowy-sync/src/client_document/extensions/helper.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/auto_exit_block.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/auto_exit_block.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/auto_format.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/auto_format.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/auto_format.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/auto_format.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/default_insert.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/default_insert.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/default_insert.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/default_insert.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/mod.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/mod.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/preserve_block_format.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_block_format.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/preserve_block_format.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_block_format.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/preserve_inline_format.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_inline_format.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/preserve_inline_format.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_inline_format.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/insert/reset_format_on_new_line.rs b/shared-lib/flowy-sync/src/client_document/extensions/insert/reset_format_on_new_line.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/insert/reset_format_on_new_line.rs rename to shared-lib/flowy-sync/src/client_document/extensions/insert/reset_format_on_new_line.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/extensions/mod.rs b/shared-lib/flowy-sync/src/client_document/extensions/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/extensions/mod.rs rename to shared-lib/flowy-sync/src/client_document/extensions/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/history.rs b/shared-lib/flowy-sync/src/client_document/history.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/history.rs rename to shared-lib/flowy-sync/src/client_document/history.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/mod.rs b/shared-lib/flowy-sync/src/client_document/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/mod.rs rename to shared-lib/flowy-sync/src/client_document/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_document/view.rs b/shared-lib/flowy-sync/src/client_document/view.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_document/view.rs rename to shared-lib/flowy-sync/src/client_document/view.rs diff --git a/shared-lib/flowy-collaboration/src/client_folder/builder.rs b/shared-lib/flowy-sync/src/client_folder/builder.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_folder/builder.rs rename to shared-lib/flowy-sync/src/client_folder/builder.rs diff --git a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs rename to shared-lib/flowy-sync/src/client_folder/folder_pad.rs diff --git a/shared-lib/flowy-collaboration/src/client_folder/mod.rs b/shared-lib/flowy-sync/src/client_folder/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_folder/mod.rs rename to shared-lib/flowy-sync/src/client_folder/mod.rs diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs rename to shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs rename to shared-lib/flowy-sync/src/client_grid/grid_builder.rs diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs rename to shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-sync/src/client_grid/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/client_grid/mod.rs rename to shared-lib/flowy-sync/src/client_grid/mod.rs diff --git a/shared-lib/flowy-collaboration/src/entities/folder_info.rs b/shared-lib/flowy-sync/src/entities/folder_info.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/folder_info.rs rename to shared-lib/flowy-sync/src/entities/folder_info.rs diff --git a/shared-lib/flowy-collaboration/src/entities/mod.rs b/shared-lib/flowy-sync/src/entities/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/mod.rs rename to shared-lib/flowy-sync/src/entities/mod.rs diff --git a/shared-lib/flowy-collaboration/src/entities/parser/doc_id.rs b/shared-lib/flowy-sync/src/entities/parser/doc_id.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/parser/doc_id.rs rename to shared-lib/flowy-sync/src/entities/parser/doc_id.rs diff --git a/shared-lib/flowy-collaboration/src/entities/parser/mod.rs b/shared-lib/flowy-sync/src/entities/parser/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/parser/mod.rs rename to shared-lib/flowy-sync/src/entities/parser/mod.rs diff --git a/shared-lib/flowy-collaboration/src/entities/revision.rs b/shared-lib/flowy-sync/src/entities/revision.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/revision.rs rename to shared-lib/flowy-sync/src/entities/revision.rs diff --git a/shared-lib/flowy-collaboration/src/entities/text_block_info.rs b/shared-lib/flowy-sync/src/entities/text_block_info.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/text_block_info.rs rename to shared-lib/flowy-sync/src/entities/text_block_info.rs diff --git a/shared-lib/flowy-collaboration/src/entities/ws_data.rs b/shared-lib/flowy-sync/src/entities/ws_data.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/entities/ws_data.rs rename to shared-lib/flowy-sync/src/entities/ws_data.rs diff --git a/shared-lib/flowy-collaboration/src/errors.rs b/shared-lib/flowy-sync/src/errors.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/errors.rs rename to shared-lib/flowy-sync/src/errors.rs diff --git a/shared-lib/flowy-collaboration/src/lib.rs b/shared-lib/flowy-sync/src/lib.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/lib.rs rename to shared-lib/flowy-sync/src/lib.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/mod.rs b/shared-lib/flowy-sync/src/protobuf/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/mod.rs rename to shared-lib/flowy-sync/src/protobuf/mod.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/folder_info.rs b/shared-lib/flowy-sync/src/protobuf/model/folder_info.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/model/folder_info.rs rename to shared-lib/flowy-sync/src/protobuf/model/folder_info.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs b/shared-lib/flowy-sync/src/protobuf/model/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/model/mod.rs rename to shared-lib/flowy-sync/src/protobuf/model/mod.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs b/shared-lib/flowy-sync/src/protobuf/model/revision.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/model/revision.rs rename to shared-lib/flowy-sync/src/protobuf/model/revision.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs b/shared-lib/flowy-sync/src/protobuf/model/text_block_info.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs rename to shared-lib/flowy-sync/src/protobuf/model/text_block_info.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/ws_data.rs b/shared-lib/flowy-sync/src/protobuf/model/ws_data.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/model/ws_data.rs rename to shared-lib/flowy-sync/src/protobuf/model/ws_data.rs diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/folder_info.proto b/shared-lib/flowy-sync/src/protobuf/proto/folder_info.proto similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/proto/folder_info.proto rename to shared-lib/flowy-sync/src/protobuf/proto/folder_info.proto diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto b/shared-lib/flowy-sync/src/protobuf/proto/revision.proto similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto rename to shared-lib/flowy-sync/src/protobuf/proto/revision.proto diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto b/shared-lib/flowy-sync/src/protobuf/proto/text_block_info.proto similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto rename to shared-lib/flowy-sync/src/protobuf/proto/text_block_info.proto diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/ws_data.proto b/shared-lib/flowy-sync/src/protobuf/proto/ws_data.proto similarity index 100% rename from shared-lib/flowy-collaboration/src/protobuf/proto/ws_data.proto rename to shared-lib/flowy-sync/src/protobuf/proto/ws_data.proto diff --git a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs b/shared-lib/flowy-sync/src/server_document/document_manager.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/server_document/document_manager.rs rename to shared-lib/flowy-sync/src/server_document/document_manager.rs diff --git a/shared-lib/flowy-collaboration/src/server_document/document_pad.rs b/shared-lib/flowy-sync/src/server_document/document_pad.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/server_document/document_pad.rs rename to shared-lib/flowy-sync/src/server_document/document_pad.rs diff --git a/shared-lib/flowy-collaboration/src/server_document/mod.rs b/shared-lib/flowy-sync/src/server_document/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/server_document/mod.rs rename to shared-lib/flowy-sync/src/server_document/mod.rs diff --git a/shared-lib/flowy-collaboration/src/server_folder/folder_manager.rs b/shared-lib/flowy-sync/src/server_folder/folder_manager.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/server_folder/folder_manager.rs rename to shared-lib/flowy-sync/src/server_folder/folder_manager.rs diff --git a/shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs b/shared-lib/flowy-sync/src/server_folder/folder_pad.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs rename to shared-lib/flowy-sync/src/server_folder/folder_pad.rs diff --git a/shared-lib/flowy-collaboration/src/server_folder/mod.rs b/shared-lib/flowy-sync/src/server_folder/mod.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/server_folder/mod.rs rename to shared-lib/flowy-sync/src/server_folder/mod.rs diff --git a/shared-lib/flowy-collaboration/src/synchronizer.rs b/shared-lib/flowy-sync/src/synchronizer.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/synchronizer.rs rename to shared-lib/flowy-sync/src/synchronizer.rs diff --git a/shared-lib/flowy-collaboration/src/util.rs b/shared-lib/flowy-sync/src/util.rs similarity index 100% rename from shared-lib/flowy-collaboration/src/util.rs rename to shared-lib/flowy-sync/src/util.rs From 1f30a77f1d43681840f342887721b61973508193 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 20 Mar 2022 17:17:06 +0800 Subject: [PATCH 053/179] feat: save text cell data --- frontend/app_flowy/lib/plugin/plugin.dart | 6 - .../lib/workspace/application/appearance.dart | 14 +- .../grid/cell_bloc/text_cell_bloc.dart | 1 + .../workspace/application/grid/grid_bloc.dart | 56 +++---- .../application/grid/grid_block_service.dart | 56 ++++--- .../application/grid/grid_service.dart | 4 +- .../workspace/application/grid/row_bloc.dart | 34 ++--- .../home/menu/app/section/section.dart | 8 +- .../presentation/plugins/blank/blank.dart | 2 +- .../presentation/plugins/doc/document.dart | 84 +---------- .../presentation/plugins/grid/grid.dart | 6 +- .../plugins/grid/src/grid_page.dart | 72 ++++----- .../grid/src/widgets/content/grid_row.dart | 139 +++++++++--------- .../grid/src/widgets/content/text_cell.dart | 39 +++-- .../grid/src/widgets/header/header.dart | 18 ++- .../plugins/widgets/left_bar_item.dart | 74 ++++++++++ .../packages/flowy_infra/lib/notifier.dart | 21 ++- .../flowy-grid-data-model/grid.pb.dart | 16 +- .../flowy-grid-data-model/grid.pbjson.dart | 4 +- .../flowy-grid/dart_notification.pbenum.dart | 8 +- .../flowy-grid/dart_notification.pbjson.dart | 8 +- .../flowy-grid/src/dart_notification.rs | 8 +- frontend/rust-lib/flowy-grid/src/manager.rs | 2 +- .../src/protobuf/model/dart_notification.rs | 22 +-- .../protobuf/proto/dart_notification.proto | 6 +- .../src/services/block_meta_editor.rs | 35 +++-- .../flowy-grid/src/services/row/row_loader.rs | 6 +- .../flowy-revision/src/rev_manager.rs | 2 + .../src/entities/grid.rs | 10 +- .../src/protobuf/model/grid.rs | 78 +++++----- .../src/protobuf/proto/grid.proto | 2 +- .../src/client_grid/grid_block_meta_pad.rs | 37 ++--- 32 files changed, 473 insertions(+), 405 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index 607ebaab53..8d30b122ad 100644 --- a/frontend/app_flowy/lib/plugin/plugin.dart +++ b/frontend/app_flowy/lib/plugin/plugin.dart @@ -61,12 +61,6 @@ abstract class PluginConfig { } abstract class PluginDisplay with NavigationItem { - @override - Widget get leftBarItem; - - @override - Widget? get rightBarItem; - List get navigationItems; PublishNotifier? get notifier => null; diff --git a/frontend/app_flowy/lib/workspace/application/appearance.dart b/frontend/app_flowy/lib/workspace/application/appearance.dart index 87cd7e1af8..ffd7e18c92 100644 --- a/frontend/app_flowy/lib/workspace/application/appearance.dart +++ b/frontend/app_flowy/lib/workspace/application/appearance.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:app_flowy/user/application/user_settings_service.dart'; import 'package:equatable/equatable.dart'; import 'package:flowy_infra/theme.dart'; @@ -11,7 +13,7 @@ class AppearanceSettingModel extends ChangeNotifier with EquatableMixin { AppearanceSettings setting; AppTheme _theme; Locale _locale; - CancelableOperation? _saveOperation; + Timer? _saveOperation; AppearanceSettingModel(this.setting) : _theme = AppTheme.fromName(name: setting.theme), @@ -21,12 +23,10 @@ class AppearanceSettingModel extends ChangeNotifier with EquatableMixin { Locale get locale => _locale; Future save() async { - _saveOperation?.cancel; - _saveOperation = CancelableOperation.fromFuture( - Future.delayed(const Duration(seconds: 1), () async { - await UserSettingsService().setAppearanceSettings(setting); - }), - ); + _saveOperation?.cancel(); + _saveOperation = Timer(const Duration(seconds: 2), () async { + await UserSettingsService().setAppearanceSettings(setting); + }); } @override diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 80bc722be7..407cde3d2c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -17,6 +17,7 @@ class TextCellBloc extends Bloc { initial: (_InitialCell value) async {}, updateText: (_UpdateText value) { service.updateCell(data: value.text); + emit(state.copyWith(content: value.text)); }, ); }, 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 1db06d815c..fd2fefbac5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; @@ -32,7 +33,7 @@ class GridBloc extends Bloc { delete: (_Delete value) {}, rename: (_Rename value) {}, updateDesc: (_Desc value) {}, - didLoadRows: (_DidLoadRows value) { + rowsDidUpdate: (_RowsDidUpdate value) { emit(state.copyWith(rows: value.rows)); }, ); @@ -47,10 +48,19 @@ class GridBloc extends Bloc { return super.close(); } - Future _startGridListening() async { - _blockService.didLoadRowscallback = (rows) { - add(GridEvent.didLoadRows(rows)); - }; + Future _initGridBlockService(Grid grid, List fields) async { + _blockService = GridBlockService( + gridId: grid.id, + fields: fields, + blockOrders: grid.blockOrders, + ); + + _blockService.rowsUpdateNotifier.addPublishListener((result) { + result.fold( + (rows) => add(GridEvent.rowsDidUpdate(rows)), + (err) => Log.error('$err'), + ); + }); _gridListener.start(); } @@ -70,36 +80,18 @@ class GridBloc extends Bloc { final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); return Future( () => result.fold( - (fields) => _loadGridBlocks(grid, fields.items, emit), + (fields) { + _initGridBlockService(grid, fields.items); + emit(state.copyWith( + grid: Some(grid), + fields: Some(fields.items), + loadingState: GridLoadingState.finish(left(unit)), + )); + }, (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), ), ); } - - Future _loadGridBlocks(Grid grid, List fields, Emitter emit) async { - final result = await service.getGridBlocks(gridId: grid.id, blockOrders: grid.blockOrders); - result.fold( - (repeatedGridBlock) { - final gridBlocks = repeatedGridBlock.items; - final gridId = view.id; - _blockService = GridBlockService( - gridId: gridId, - fields: fields, - gridBlocks: gridBlocks, - ); - final rows = _blockService.rows(); - - _startGridListening(); - emit(state.copyWith( - grid: Some(grid), - fields: Some(fields), - rows: rows, - loadingState: GridLoadingState.finish(left(unit)), - )); - }, - (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)), rows: [])), - ); - } } @freezed @@ -109,7 +101,7 @@ abstract class GridEvent with _$GridEvent { const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.didLoadRows(List rows) = _DidLoadRows; + const factory GridEvent.rowsDidUpdate(List rows) = _RowsDidUpdate; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 3672a910f4..f84278399c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -1,5 +1,7 @@ import 'dart:collection'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; @@ -9,40 +11,38 @@ import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; - import 'grid_service.dart'; -typedef DidLoadRowsCallback = void Function(List); -typedef GridBlockUpdateNotifiedValue = Either; +typedef RowsUpdateNotifierValue = Either, FlowyError>; class GridBlockService { String gridId; List fields; LinkedHashMap blockMap = LinkedHashMap(); late GridBlockListener _blockListener; - DidLoadRowsCallback? didLoadRowscallback; + PublishNotifier rowsUpdateNotifier = PublishNotifier(); - GridBlockService({required this.gridId, required this.fields, required List gridBlocks}) { - for (final gridBlock in gridBlocks) { - blockMap[gridBlock.blockId] = gridBlock; - } + GridBlockService({required this.gridId, required this.fields, required List blockOrders}) { + _loadGridBlocks(blockOrders: blockOrders); _blockListener = GridBlockListener(gridId: gridId); - _blockListener.blockUpdateNotifier.addPublishListener((result) { - result.fold((blockId) { - // - }, (err) => null); + _blockListener.rowsUpdateNotifier.addPublishListener((result) { + result.fold( + (blockId) => _loadGridBlocks(blockOrders: [GridBlockOrder.create()..blockId = blockId.value]), + (err) => Log.error(err), + ); }); + _blockListener.start(); } - List rows() { + List buildRows() { List rows = []; blockMap.forEach((_, GridBlock gridBlock) { rows.addAll(gridBlock.rowOrders.map( (rowOrder) => GridRowData( gridId: gridId, fields: fields, - blockId: gridBlock.blockId, + blockId: gridBlock.id, rowId: rowOrder.rowId, height: rowOrder.height.toDouble(), ), @@ -54,11 +54,29 @@ class GridBlockService { Future stop() async { await _blockListener.stop(); } + + void _loadGridBlocks({required List blockOrders}) { + final payload = QueryGridBlocksPayload.create() + ..gridId = gridId + ..blockOrders.addAll(blockOrders); + + GridEventGetGridBlocks(payload).send().then((result) { + result.fold( + (repeatedBlocks) { + for (final gridBlock in repeatedBlocks.items) { + blockMap[gridBlock.id] = gridBlock; + } + rowsUpdateNotifier.value = left(buildRows()); + }, + (err) => rowsUpdateNotifier.value = right(err), + ); + }); + } } class GridBlockListener { final String gridId; - PublishNotifier blockUpdateNotifier = PublishNotifier(); + PublishNotifier> rowsUpdateNotifier = PublishNotifier(comparable: null); StreamSubscription? _subscription; late GridNotificationParser _parser; @@ -77,10 +95,10 @@ class GridBlockListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.GridDidUpdateBlock: + case GridNotification.BlockDidUpdateRow: result.fold( - (payload) => blockUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), - (error) => blockUpdateNotifier.value = right(error), + (payload) => rowsUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), + (error) => rowsUpdateNotifier.value = right(error), ); break; @@ -91,6 +109,6 @@ class GridBlockListener { Future stop() async { await _subscription?.cancel(); - blockUpdateNotifier.dispose(); + rowsUpdateNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 506401706b..2aafd02fba 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -13,9 +13,9 @@ class GridService { return GridEventGetGridData(payload).send(); } - Future> createRow({required String gridId, Option? upperRowId}) { + Future> createRow({required String gridId, Option? startRowId}) { CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; - upperRowId?.fold(() => null, (id) => payload.startRowId = id); + startRowId?.fold(() => null, (id) => payload.startRowId = id); return GridEventCreateRow(payload).send(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index bf13c682d7..67fcc5cbc2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -19,7 +19,7 @@ class RowBloc extends Bloc { await event.map( initial: (_InitialRow value) async { _startRowListening(); - await _loadCellDatas(emit); + await _loadRow(emit); }, createRow: (_CreateRow value) { rowService.createRow(); @@ -58,20 +58,20 @@ class RowBloc extends Bloc { listener.start(); } - Future _loadCellDatas(Emitter emit) async { - final result = await rowService.getRow(); - result.fold( - (row) { - emit(state.copyWith( - cellDatas: makeGridCellDatas(row), - rowHeight: row.height.toDouble(), - )); - }, - (e) => Log.error(e), - ); + Future _loadRow(Emitter emit) async { + final Future> cellDatas = rowService.getRow().then((result) { + return result.fold( + (row) => _makeCellDatas(row), + (e) { + Log.error(e); + return []; + }, + ); + }); + emit(state.copyWith(cellDatas: cellDatas)); } - List makeGridCellDatas(Row row) { + List _makeCellDatas(Row row) { return rowService.rowData.fields.map((field) { final cell = row.cellByFieldId[field.id]; final rowData = rowService.rowData; @@ -96,18 +96,18 @@ abstract class RowEvent with _$RowEvent { } @freezed -abstract class RowState with _$RowState { +class RowState with _$RowState { const factory RowState({ required String rowId, required double rowHeight, - required List cellDatas, + required Future> cellDatas, required bool active, }) = _RowState; factory RowState.initial(GridRowData data) => RowState( rowId: data.rowId, - active: false, rowHeight: data.height, - cellDatas: [], + cellDatas: Future(() => []), + active: false, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index dcb2d454b9..ed0a718f58 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/view/view_ext.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; @@ -64,7 +66,7 @@ class ViewSectionNotifier with ChangeNotifier { bool isDisposed = false; List _views; View? _selectedView; - CancelableOperation? _notifyListenerOperation; + Timer? _notifyListenerOperation; ViewSectionNotifier({ required BuildContext context, @@ -120,9 +122,7 @@ class ViewSectionNotifier with ChangeNotifier { void _notifyListeners() { _notifyListenerOperation?.cancel(); - _notifyListenerOperation = CancelableOperation.fromFuture( - Future.delayed(const Duration(milliseconds: 30), () {}), - ).then((_) { + _notifyListenerOperation = Timer(const Duration(milliseconds: 30), () { if (!isDisposed) { notifyListeners(); } 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 598f6971f2..05456f20f4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart @@ -40,7 +40,7 @@ class BlankPagePlugin extends Plugin { PluginType get ty => _pluginType; } -class BlankPagePluginDisplay extends PluginDisplay { +class BlankPagePluginDisplay extends PluginDisplay with NavigationItem { @override Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12); 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 f027bf3e7a..e8f0290123 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -10,14 +10,13 @@ import 'package:app_flowy/startup/startup.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'; -import 'package:app_flowy/workspace/application/view/view_service.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; +import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.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'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; import 'package:flowy_sdk/log.dart'; @@ -89,7 +88,7 @@ class DocumentPlugin implements Plugin { PluginId get id => _view.id; } -class DocumentPluginDisplay extends PluginDisplay { +class DocumentPluginDisplay extends PluginDisplay with NavigationItem { final PublishNotifier _displayNotifier = PublishNotifier(); final View _view; @@ -99,91 +98,16 @@ class DocumentPluginDisplay extends PluginDisplay { Widget buildWidget() => DocumentPage(view: _view, key: ValueKey(_view.id)); @override - Widget get leftBarItem => DocumentLeftBarItem(view: _view); + Widget get leftBarItem => ViewLeftBarItem(view: _view); @override Widget? get rightBarItem => DocumentShareButton(view: _view); @override - List get navigationItems => _makeNavigationItems(); + List get navigationItems => [this]; @override PublishNotifier? get notifier => _displayNotifier; - - List _makeNavigationItems() { - return [ - this, - ]; - } -} - -class DocumentLeftBarItem extends StatefulWidget { - final View view; - - DocumentLeftBarItem({required this.view, Key? key}) : super(key: ValueKey(view.hashCode)); - - @override - State createState() => _DocumentLeftBarItemState(); -} - -class _DocumentLeftBarItemState extends State { - final _controller = TextEditingController(); - final _focusNode = FocusNode(); - late ViewService service; - - @override - void initState() { - service = ViewService(/*view: widget.view*/); - _focusNode.addListener(_handleFocusChanged); - super.initState(); - } - - @override - void dispose() { - _controller.dispose(); - _focusNode.removeListener(_handleFocusChanged); - _focusNode.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - _controller.text = widget.view.name; - - final theme = context.watch(); - return IntrinsicWidth( - key: ValueKey(_controller.text), - child: TextField( - controller: _controller, - focusNode: _focusNode, - scrollPadding: EdgeInsets.zero, - decoration: const InputDecoration( - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - isDense: true, - ), - style: TextStyle( - color: theme.textColor, - fontSize: 14, - fontWeight: FontWeight.w500, - overflow: TextOverflow.ellipsis, - ), - // cursorColor: widget.cursorColor, - // obscureText: widget.enableObscure, - ), - ); - } - - void _handleFocusChanged() { - if (_controller.text.isEmpty) { - _controller.text = widget.view.name; - return; - } - - if (_controller.text != widget.view.name) { - service.updateView(viewId: widget.view.id, name: _controller.text); - } - } } class DocumentShareButton extends StatelessWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart index cf6b4c9032..adc2a91fa9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.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'; @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => false; + bool get creatable => true; } class GridPlugin extends Plugin { @@ -56,7 +56,7 @@ class GridPluginDisplay extends PluginDisplay { GridPluginDisplay({required View view, Key? key}) : _view = view; @override - Widget get leftBarItem => const FlowyText.medium("Grid demo", fontSize: 12); + Widget get leftBarItem => ViewLeftBarItem(view: _view); @override Widget buildWidget() => GridPage(view: _view); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 4e7747ac1d..1d6bc07891 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 @@ -84,42 +84,38 @@ class _FlowyGridState extends State { @override Widget build(BuildContext context) { return BlocBuilder( + buildWhen: (previous, current) => previous.fields != current.fields, builder: (context, state) { return state.fields.fold( () => const Center(child: CircularProgressIndicator.adaptive()), - (fields) => _renderGrid(context, fields), + (fields) => _wrapScrollbar(fields, [ + _buildHeader(fields), + _buildRows(context), + const GridFooter(), + ]), ); }, ); } - Widget _renderGrid(BuildContext context, List fields) { - return Stack( - children: [ - StyledSingleChildScrollView( - controller: _scrollController.horizontalController, - axis: Axis.horizontal, - child: SizedBox( - width: GridLayout.headerWidth(fields), - child: CustomScrollView( - physics: StyledScrollPhysics(), - controller: _scrollController.verticalController, - slivers: [ - _buildHeader(fields), - _buildRows(context), - const GridFooter(), - ], - ), + Widget _wrapScrollbar(List fields, List children) { + return ScrollbarListStack( + axis: Axis.vertical, + controller: _scrollController.verticalController, + barSize: GridSize.scrollBarSize, + child: StyledSingleChildScrollView( + controller: _scrollController.horizontalController, + axis: Axis.horizontal, + child: SizedBox( + width: GridLayout.headerWidth(fields), + child: CustomScrollView( + physics: StyledScrollPhysics(), + controller: _scrollController.verticalController, + slivers: [...children], ), ), - ScrollbarListStack( - axis: Axis.vertical, - controller: _scrollController.verticalController, - barSize: GridSize.scrollBarSize, - child: Container(), - ).padding(right: 0, top: GridSize.headerHeight, bottom: GridSize.scrollBarSize), - ], - ); + ), + ).padding(right: 0, top: GridSize.headerHeight, bottom: GridSize.scrollBarSize); } Widget _buildHeader(List fields) { @@ -131,15 +127,21 @@ class _FlowyGridState extends State { } Widget _buildRows(BuildContext context) { - return SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) { - final rowData = context.read().state.rows[index]; - return GridRowWidget(data: rowData); - }, - childCount: context.read().state.rows.length, - addRepaintBoundaries: true, - ), + return BlocBuilder( + buildWhen: (previous, current) => previous.rows.length != current.rows.length, + builder: (context, state) { + return SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) { + final rowData = context.read().state.rows[index]; + return GridRowWidget(data: rowData); + }, + childCount: context.read().state.rows.length, + addRepaintBoundaries: true, + addAutomaticKeepAlives: true, + ), + ); + }, ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index f062202744..3efc47d33c 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -11,7 +11,7 @@ import 'cell_container.dart'; class GridRowWidget extends StatefulWidget { final GridRowData data; - GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.rowId)); + GridRowWidget({required this.data, Key? key}) : super(key: ValueKey(data.rowId)); @override State createState() => _GridRowWidgetState(); @@ -30,28 +30,25 @@ class _GridRowWidgetState extends State { Widget build(BuildContext context) { return BlocProvider.value( value: _rowBloc, - child: GestureDetector( - behavior: HitTestBehavior.translucent, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), - onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const LeadingRow(), - _buildCells(), - const TrailingRow(), - ], - ), - ); - }, - ), + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, ), ), ); @@ -62,69 +59,37 @@ class _GridRowWidgetState extends State { _rowBloc.close(); super.dispose(); } - - Widget _buildCells() { - return BlocBuilder( - buildWhen: (p, c) => p.cellDatas != c.cellDatas, - builder: (context, state) { - return Row( - children: state.cellDatas - .map( - (cellData) => CellContainer( - width: cellData.field.width.toDouble(), - child: buildGridCell(cellData), - ), - ) - .toList(), - ); - }, - ); - } } -class LeadingRow extends StatelessWidget { - const LeadingRow({Key? key}) : super(key: key); +class _RowLeading extends StatelessWidget { + const _RowLeading({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocSelector( selector: (state) => state.active, builder: (context, isActive) { - return SizedBox( - width: GridSize.leadingHeaderPadding, - child: isActive - ? Row( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - AppendRowButton(), - ], - ) - : null, - ); + return SizedBox(width: GridSize.leadingHeaderPadding, child: isActive ? _activeWidget() : null); }, ); } + + Widget _activeWidget() { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + AppendRowButton(), + ], + ); + } } -class TrailingRow extends StatelessWidget { - const TrailingRow({Key? key}) : super(key: key); +class _RowTrailing extends StatelessWidget { + const _RowTrailing({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final theme = context.watch(); - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - - return BlocBuilder( - builder: (context, state) { - return Container( - width: GridSize.trailHeaderPadding, - decoration: BoxDecoration( - border: Border(bottom: borderSide), - ), - padding: GridSize.cellContentInsets, - ); - }, - ); + return const SizedBox(); } } @@ -143,3 +108,37 @@ class AppendRowButton extends StatelessWidget { ); } } + +class _RowCells extends StatelessWidget { + const _RowCells({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) => previous.cellDatas != current.cellDatas, + builder: (context, state) { + return FutureBuilder( + future: state.cellDatas, + builder: builder, + ); + }, + ); + } + + Widget builder(context, AsyncSnapshot snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.done: + List cellDatas = snapshot.data; + return Row(children: cellDatas.map(_toCell).toList()); + default: + return const SizedBox(); + } + } + + Widget _toCell(GridCellData data) { + return CellContainer( + width: data.field.width.toDouble(), + child: buildGridCell(data), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 71ab0c41bd..937c5d84ab 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,6 +1,9 @@ +import 'dart:async'; + import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -19,27 +22,40 @@ class GridTextCell extends StatefulWidget { class _GridTextCellState extends State { late TextEditingController _controller; + Timer? _delayOperation; final _focusNode = FocusNode(); - late TextCellBloc _cellBloc; + TextCellBloc? _cellBloc; @override void initState() { _cellBloc = getIt(param1: widget.cellData); - _controller = TextEditingController(text: _cellBloc.state.content); - _focusNode.addListener(_focusChanged); + _controller = TextEditingController(text: _cellBloc!.state.content); + _focusNode.addListener(save); super.initState(); } @override Widget build(BuildContext context) { return BlocProvider.value( - value: _cellBloc, + value: _cellBloc!, child: BlocBuilder( + buildWhen: (previous, current) { + return _controller.text != current.content; + }, builder: (context, state) { return TextField( controller: _controller, focusNode: _focusNode, - onChanged: (value) {}, + onChanged: (value) { + Log.info("On change"); + save(); + }, + onEditingComplete: () { + Log.info("On complete"); + }, + onSubmitted: (value) { + Log.info("On submit"); + }, maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), decoration: const InputDecoration( @@ -55,13 +71,18 @@ class _GridTextCellState extends State { @override Future dispose() async { - _cellBloc.close(); - _focusNode.removeListener(_focusChanged); + _cellBloc?.close(); + _cellBloc = null; + _focusNode.removeListener(save); _focusNode.dispose(); super.dispose(); } - void _focusChanged() { - _cellBloc.add(TextCellEvent.updateText(_controller.text)); + Future save() async { + _delayOperation?.cancel(); + _delayOperation = Timer(const Duration(seconds: 2), () { + _cellBloc?.add(TextCellEvent.updateText(_controller.text)); + }); + // and later, before the timer goes off... } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 83d24535f4..e84640a584 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -42,6 +42,7 @@ class GridHeader extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch(); return BlocProvider( create: (context) => getIt(param1: fields)..add(const ColumnEvent.initial()), child: BlocBuilder( @@ -55,13 +56,16 @@ class GridHeader extends StatelessWidget { ) .toList(); - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const LeadingHeaderCell(), - ...headers, - const TrailingHeaderCell(), - ], + return Container( + color: theme.surface, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingHeaderCell(), + ...headers, + const TrailingHeaderCell(), + ], + ), ); }, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart new file mode 100644 index 0000000000..7c1e819cc5 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart @@ -0,0 +1,74 @@ +import 'package:app_flowy/workspace/application/view/view_service.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class ViewLeftBarItem extends StatefulWidget { + final View view; + + ViewLeftBarItem({required this.view, Key? key}) : super(key: ValueKey(view.hashCode)); + + @override + State createState() => _ViewLeftBarItemState(); +} + +class _ViewLeftBarItemState extends State { + final _controller = TextEditingController(); + final _focusNode = FocusNode(); + late ViewService serviceService; + + @override + void initState() { + serviceService = ViewService(/*view: widget.view*/); + _focusNode.addListener(_handleFocusChanged); + super.initState(); + } + + @override + void dispose() { + _controller.dispose(); + _focusNode.removeListener(_handleFocusChanged); + _focusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + _controller.text = widget.view.name; + + final theme = context.watch(); + return IntrinsicWidth( + key: ValueKey(_controller.text), + child: TextField( + controller: _controller, + focusNode: _focusNode, + scrollPadding: EdgeInsets.zero, + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + style: TextStyle( + color: theme.textColor, + fontSize: 14, + fontWeight: FontWeight.w500, + overflow: TextOverflow.ellipsis, + ), + // cursorColor: widget.cursorColor, + // obscureText: widget.enableObscure, + ), + ); + } + + void _handleFocusChanged() { + if (_controller.text.isEmpty) { + _controller.text = widget.view.name; + return; + } + + if (_controller.text != widget.view.name) { + serviceService.updateView(viewId: widget.view.id, name: _controller.text); + } + } +} diff --git a/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart b/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart index 0e0c6bc4cf..0079ba51a1 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart @@ -1,10 +1,29 @@ import 'package:flutter/material.dart'; +abstract class Comparable { + bool compare(T? previous, T? current); +} + +class ObjectComparable extends Comparable { + @override + bool compare(T? previous, T? current) { + return previous == current; + } +} + class PublishNotifier extends ChangeNotifier { T? _value; + Comparable? comparable = ObjectComparable(); + + PublishNotifier({this.comparable}); set value(T newValue) { - if (_value != newValue) { + if (comparable != null) { + if (comparable!.compare(_value, newValue)) { + _value = newValue; + notifyListeners(); + } + } else { _value = newValue; notifyListeners(); } 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 bc713bbdb8..4462ce8b10 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 @@ -609,19 +609,19 @@ class GridBlockOrder extends $pb.GeneratedMessage { class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false ; GridBlock._() : super(); factory GridBlock({ - $core.String? blockId, + $core.String? id, $core.Iterable? rowOrders, }) { final _result = create(); - if (blockId != null) { - _result.blockId = blockId; + if (id != null) { + _result.id = id; } if (rowOrders != null) { _result.rowOrders.addAll(rowOrders); @@ -650,13 +650,13 @@ class GridBlock extends $pb.GeneratedMessage { static GridBlock? _defaultInstance; @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); + $core.String get id => $_getSZ(0); @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } + set id($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); + $core.bool hasId() => $_has(0); @$pb.TagNumber(1) - void clearBlockId() => clearField(1); + void clearId() => clearField(1); @$pb.TagNumber(2) $core.List get rowOrders => $_getList(1); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 5e24c82178..cde3112874 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 @@ -135,13 +135,13 @@ final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg const GridBlock$json = const { '1': 'GridBlock', '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'row_orders', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSKAoKcm93X29yZGVycxgCIAMoCzIJLlJvd09yZGVyUglyb3dPcmRlcnM='); +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEigKCnJvd19vcmRlcnMYAiADKAsyCS5Sb3dPcmRlclIJcm93T3JkZXJz'); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index f68b10f292..27985d016c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -11,15 +11,15 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); - static const GridNotification GridDidUpdateBlock = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateBlock'); static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock'); - static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); - static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); + static const GridNotification BlockDidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockDidUpdateRow'); + static const GridNotification GridDidUpdateCells = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); + static const GridNotification GridDidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); static const $core.List values = [ Unknown, - GridDidUpdateBlock, GridDidCreateBlock, + BlockDidUpdateRow, GridDidUpdateCells, GridDidUpdateFields, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index b266e63e09..0eebf85cc6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -13,12 +13,12 @@ const GridNotification$json = const { '1': 'GridNotification', '2': const [ const {'1': 'Unknown', '2': 0}, - const {'1': 'GridDidUpdateBlock', '2': 10}, const {'1': 'GridDidCreateBlock', '2': 11}, - const {'1': 'GridDidUpdateCells', '2': 20}, - const {'1': 'GridDidUpdateFields', '2': 30}, + const {'1': 'BlockDidUpdateRow', '2': 20}, + const {'1': 'GridDidUpdateCells', '2': 30}, + const {'1': 'GridDidUpdateFields', '2': 40}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIVChFCbG9ja0RpZFVwZGF0ZVJvdxAUEhYKEkdyaWREaWRVcGRhdGVDZWxscxAeEhcKE0dyaWREaWRVcGRhdGVGaWVsZHMQKA=='); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 82ab35bdee..927b71d957 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -5,11 +5,13 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; #[derive(ProtoBuf_Enum, Debug)] pub enum GridNotification { Unknown = 0, - GridDidUpdateBlock = 10, + GridDidCreateBlock = 11, - GridDidUpdateCells = 20, - GridDidUpdateFields = 30, + BlockDidUpdateRow = 20, + + GridDidUpdateCells = 30, + GridDidUpdateFields = 40, } impl std::default::Default for GridNotification { diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 75499acdac..e4f24a8547 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -83,7 +83,7 @@ impl GridManager { Ok(()) } - #[tracing::instrument(level = "debug", skip(self), err)] + // #[tracing::instrument(level = "debug", skip(self), err)] pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.editor_map.get(grid_id) { None => Err(FlowyError::internal().context("Should call open_grid function first")), diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 72b3f12abd..4562b238c0 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -26,10 +26,10 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridNotification { Unknown = 0, - GridDidUpdateBlock = 10, GridDidCreateBlock = 11, - GridDidUpdateCells = 20, - GridDidUpdateFields = 30, + BlockDidUpdateRow = 20, + GridDidUpdateCells = 30, + GridDidUpdateFields = 40, } impl ::protobuf::ProtobufEnum for GridNotification { @@ -40,10 +40,10 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), - 10 => ::std::option::Option::Some(GridNotification::GridDidUpdateBlock), 11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock), - 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), - 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), + 20 => ::std::option::Option::Some(GridNotification::BlockDidUpdateRow), + 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), + 40 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), _ => ::std::option::Option::None } } @@ -51,8 +51,8 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn values() -> &'static [Self] { static values: &'static [GridNotification] = &[ GridNotification::Unknown, - GridNotification::GridDidUpdateBlock, GridNotification::GridDidCreateBlock, + GridNotification::BlockDidUpdateRow, GridNotification::GridDidUpdateCells, GridNotification::GridDidUpdateFields, ]; @@ -83,10 +83,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x80\x01\n\x10GridNotification\x12\x0b\n\ - \x07Unknown\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12Gri\ - dDidCreateBlock\x10\x0b\x12\x16\n\x12GridDidUpdateCells\x10\x14\x12\x17\ - \n\x13GridDidUpdateFields\x10\x1eb\x06proto3\ + \n\x17dart_notification.proto*\x7f\n\x10GridNotification\x12\x0b\n\x07Un\ + known\x10\0\x12\x16\n\x12GridDidCreateBlock\x10\x0b\x12\x15\n\x11BlockDi\ + dUpdateRow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x17\n\x13\ + GridDidUpdateFields\x10(b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 0262b34477..be25f80f3b 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -2,8 +2,8 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; - GridDidUpdateBlock = 10; GridDidCreateBlock = 11; - GridDidUpdateCells = 20; - GridDidUpdateFields = 30; + BlockDidUpdateRow = 20; + GridDidUpdateCells = 30; + GridDidUpdateFields = 40; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index ca3f99b363..4a73ccd1b1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -46,7 +46,9 @@ impl GridBlockMetaEditorManager { Ok(manager) } + // #[tracing::instrument(level = "trace", skip(self))] pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + debug_assert!(!block_id.is_empty()); match self.editor_map.get(block_id) { None => { tracing::error!("The is a fatal error, block is not exist"); @@ -68,7 +70,7 @@ impl GridBlockMetaEditorManager { .insert(row_meta.id.clone(), row_meta.block_id.clone()); let editor = self.get_editor(&row_meta.block_id).await?; let row_count = editor.create_row(row_meta, start_row_id).await?; - self.notify_did_update_block(block_id).await?; + self.notify_block_did_update_row(&block_id).await?; Ok(row_count) } @@ -85,7 +87,7 @@ impl GridBlockMetaEditorManager { row_count = editor.create_row(row.clone(), None).await?; } changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); - let _ = self.notify_did_update_block(&block_id).await?; + let _ = self.notify_block_did_update_row(&block_id).await?; } Ok(changesets) @@ -108,7 +110,7 @@ impl GridBlockMetaEditorManager { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - let _ = self.notify_did_update_block(&editor.block_id).await?; + let _ = self.notify_block_did_update_row(&editor.block_id).await?; Ok(()) } @@ -183,11 +185,9 @@ impl GridBlockMetaEditorManager { } } - async fn notify_did_update_block(&self, block_id: &str) -> FlowyResult<()> { - let block_id = GridBlockId { - value: block_id.to_owned(), - }; - send_dart_notification(&self.grid_id, GridNotification::GridDidUpdateBlock) + async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { + let block_id: GridBlockId = block_id.into(); + send_dart_notification(&self.grid_id, GridNotification::BlockDidUpdateRow) .payload(block_id) .send(); Ok(()) @@ -277,7 +277,7 @@ impl ClientGridBlockMetaEditor { let mut row_count = 0; let _ = self .modify(|pad| { - let change = pad.add_row(row, start_row_id)?; + let change = pad.add_row_meta(row, start_row_id)?; row_count = pad.number_of_rows(); Ok(change) }) @@ -298,13 +298,22 @@ impl ClientGridBlockMetaEditor { Ok(row_count) } - pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult { + let row_id = changeset.row_id.clone(); let _ = self.modify(|pad| Ok(pad.update_row(changeset)?)).await?; - Ok(()) + let mut row_metas = self.get_row_metas(Some(vec![row_id.clone()])).await?; + debug_assert_eq!(row_metas.len(), 1); + + if row_metas.is_empty() { + return Err(FlowyError::record_not_found().context(format!("Can't find the row with id: {}", &row_id))); + } else { + let a = (**row_metas.pop().as_ref().unwrap()).clone(); + Ok(a) + } } pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { - let row_metas = self.pad.read().await.get_rows(row_ids)?; + let row_metas = self.pad.read().await.get_row_metas(row_ids)?; Ok(row_metas) } @@ -313,7 +322,7 @@ impl ClientGridBlockMetaEditor { .pad .read() .await - .get_rows(row_ids)? + .get_row_metas(row_ids)? .iter() .map(RowOrder::from) .collect::>(); diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index bf2f62c776..70cea1b4c8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -43,10 +43,10 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec) -> FlowyResult { Ok(block_meta_snapshots .into_iter() - .map(|row_metas_per_block| { - let row_orders = make_row_orders_from_row_metas(&row_metas_per_block.row_metas); + .map(|block_meta_data| { + let row_orders = make_row_orders_from_row_metas(&block_meta_data.row_metas); GridBlock { - block_id: row_metas_per_block.block_id, + id: block_meta_data.block_id, row_orders, } }) diff --git a/frontend/rust-lib/flowy-revision/src/rev_manager.rs b/frontend/rust-lib/flowy-revision/src/rev_manager.rs index 3cd9b54de0..68d8db6f27 100644 --- a/frontend/rust-lib/flowy-revision/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-revision/src/rev_manager.rs @@ -67,6 +67,7 @@ impl RevisionManager { } } + #[tracing::instrument(level = "debug", skip_all, fields(object_id) err)] pub async fn load(&mut self, cloud: Option>) -> FlowyResult where B: RevisionObjectBuilder, @@ -80,6 +81,7 @@ impl RevisionManager { .load() .await?; self.rev_id_counter.set(rev_id); + tracing::Span::current().record("object_id", &self.object_id.as_str()); B::build_object(&self.object_id, revisions) } 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 c195a85c24..e9a80c4be3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -181,7 +181,7 @@ pub struct GridBlockOrder { #[derive(Debug, Default, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] - pub block_id: String, + pub id: String, #[pb(index = 2)] pub row_orders: Vec, @@ -190,7 +190,7 @@ pub struct GridBlock { impl GridBlock { pub fn new(block_id: &str, row_orders: Vec) -> Self { Self { - block_id: block_id.to_owned(), + id: block_id.to_owned(), row_orders, } } @@ -269,6 +269,12 @@ impl AsRef for GridBlockId { } } +impl std::convert::From<&str> for GridBlockId { + fn from(s: &str) -> Self { + GridBlockId { value: s.to_owned() } + } +} + #[derive(ProtoBuf, Default)] pub struct CreateRowPayload { #[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 fc538875c9..f947f70851 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 @@ -2111,7 +2111,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { #[derive(PartialEq,Clone,Default)] pub struct GridBlock { // message fields - pub block_id: ::std::string::String, + pub id: ::std::string::String, pub row_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -2129,30 +2129,30 @@ impl GridBlock { ::std::default::Default::default() } - // string block_id = 1; + // string id = 1; - pub fn get_block_id(&self) -> &str { - &self.block_id + pub fn get_id(&self) -> &str { + &self.id } - pub fn clear_block_id(&mut self) { - self.block_id.clear(); + pub fn clear_id(&mut self) { + self.id.clear(); } // Param is passed by value, moved - pub fn set_block_id(&mut self, v: ::std::string::String) { - self.block_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_block_id(&mut self) -> &mut ::std::string::String { - &mut self.block_id + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id } // Take field - pub fn take_block_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) } // repeated .RowOrder row_orders = 2; @@ -2196,7 +2196,7 @@ impl ::protobuf::Message for GridBlock { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; @@ -2213,8 +2213,8 @@ impl ::protobuf::Message for GridBlock { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.block_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.block_id); + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); } for value in &self.row_orders { let len = value.compute_size(); @@ -2226,8 +2226,8 @@ impl ::protobuf::Message for GridBlock { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.block_id.is_empty() { - os.write_string(1, &self.block_id)?; + if !self.id.is_empty() { + os.write_string(1, &self.id)?; } for v in &self.row_orders { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; @@ -2273,9 +2273,9 @@ impl ::protobuf::Message for GridBlock { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "block_id", - |m: &GridBlock| { &m.block_id }, - |m: &mut GridBlock| { &mut m.block_id }, + "id", + |m: &GridBlock| { &m.id }, + |m: &mut GridBlock| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "row_orders", @@ -2298,7 +2298,7 @@ impl ::protobuf::Message for GridBlock { impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { - self.block_id.clear(); + self.id.clear(); self.row_orders.clear(); self.unknown_fields.clear(); } @@ -4091,24 +4091,24 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ \x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\ \x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockO\ - rder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"P\n\tGridBloc\ - k\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_order\ - s\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\ - \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ - \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ - \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ - \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ - e\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ - \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ - _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\ - \x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"d\n\x11QueryField\ - Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ - ld_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\ - e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrd\ - erR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ - \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\ + rder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBloc\ + k\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ + \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ + \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ + \x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b\ + 2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\ + \x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\ + \x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01\ + (\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstart\ + RowIdB\x15\n\x13one_of_start_row_id\"d\n\x11QueryFieldPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ + \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ + locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ + \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ + s\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ + ridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x15\n\x06\ + row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 2ce7c429d5..00dee86f6b 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 @@ -44,7 +44,7 @@ message GridBlockOrder { string block_id = 1; } message GridBlock { - string block_id = 1; + string id = 1; repeated RowOrder row_orders = 2; } message Cell { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 7bfef998c2..768c7bf60a 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -47,20 +47,21 @@ impl GridBlockMetaPad { Self::from_delta(block_delta) } - pub fn add_row( + #[tracing::instrument(level = "trace", skip(self, row), err)] + pub fn add_row_meta( &mut self, row: RowMeta, start_row_id: Option, ) -> CollaborateResult> { self.modify(|rows| { - if let Some(upper_row_id) = start_row_id { - if upper_row_id.is_empty() { + if let Some(start_row_id) = start_row_id { + if start_row_id.is_empty() { rows.insert(0, Arc::new(row)); return Ok(Some(())); } - if let Some(index) = rows.iter().position(|row| row.id == upper_row_id) { - rows.insert(index, Arc::new(row)); + if let Some(index) = rows.iter().position(|row| row.id == start_row_id) { + rows.insert(index + 1, Arc::new(row)); return Ok(Some(())); } } @@ -77,7 +78,7 @@ impl GridBlockMetaPad { }) } - pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { + pub fn get_row_metas(&self, row_ids: Option>) -> CollaborateResult>> { match row_ids { None => Ok(self.row_metas.to_vec()), Some(row_ids) => { @@ -229,7 +230,7 @@ mod tests { visibility: false, }; - let change = pad.add_row(row, None).unwrap().unwrap(); + let change = pad.add_row_meta(row, None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# @@ -243,19 +244,19 @@ mod tests { let row_2 = test_row_meta("2", &pad); let row_3 = test_row_meta("3", &pad); - let change = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + let change = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); - let change = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + let change = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":106},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); - let change = pad.add_row(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); + let change = pad.add_row_meta(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":114},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# @@ -283,9 +284,9 @@ mod tests { let row_2 = test_row_meta("2", &pad); let row_3 = test_row_meta("3", &pad); - let _ = pad.add_row(row_1.clone(), None).unwrap().unwrap(); - let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); - let _ = pad.add_row(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); + let _ = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap(); + let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); + let _ = pad.add_row_meta(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); assert_eq!(*pad.row_metas[0], row_3); assert_eq!(*pad.row_metas[1], row_1); @@ -299,9 +300,9 @@ mod tests { let row_2 = test_row_meta("2", &pad); let row_3 = test_row_meta("3", &pad); - let _ = pad.add_row(row_1.clone(), None).unwrap().unwrap(); - let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); - let _ = pad.add_row(row_3.clone(), Some("".to_string())).unwrap().unwrap(); + let _ = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap(); + let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); + let _ = pad.add_row_meta(row_3.clone(), Some("".to_string())).unwrap().unwrap(); assert_eq!(*pad.row_metas[0], row_3); assert_eq!(*pad.row_metas[1], row_1); @@ -320,7 +321,7 @@ mod tests { visibility: false, }; - let _ = pad.add_row(row.clone(), None).unwrap().unwrap(); + let _ = pad.add_row_meta(row.clone(), None).unwrap().unwrap(); let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), @@ -348,7 +349,7 @@ mod tests { cell_by_field_id: Default::default(), }; - let _ = pad.add_row(row, None).unwrap().unwrap(); + let _ = pad.add_row_meta(row, None).unwrap().unwrap(); let change = pad.update_row(changeset).unwrap().unwrap(); assert_eq!( From 475d5118292520811b6894e50c9f01d958fbbd5d Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 20 Mar 2022 22:38:57 +0800 Subject: [PATCH 054/179] fix: can't find overlay exists above editabletext --- .../home/menu/app/header/header.dart | 1 - .../menu/app/section/disclosure_action.dart | 2 +- .../home/menu/app/section/section.dart | 1 - .../presentation/plugins/doc/document.dart | 1 - .../doc/src/widget/toolbar/color_picker.dart | 9 ----- .../plugins/grid/src/layout/sizes.dart | 14 ++++---- .../grid/src/widgets/footer/grid_footer.dart | 2 +- .../grid/src/widgets/header/header.dart | 14 ++++---- .../grid/src/widgets/header/header_cell.dart | 29 ++++++++++++++-- .../presentation/plugins/trash/trash.dart | 4 +-- .../widgets/float_bubble/question_bubble.dart | 1 - .../presentation/widgets/pop_up_action.dart | 6 ++-- .../presentation/widgets/pop_up_window.dart | 1 + .../lib/src/flowy_overlay/flowy_overlay.dart | 7 ++-- .../lib/src/flowy_overlay/list_overlay.dart | 34 ------------------- .../lib/style_widget/button.dart | 16 ++++++--- 16 files changed, 66 insertions(+), 76 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart index da20eafc7b..b773814f2d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart @@ -81,7 +81,6 @@ class MenuAppHeader extends StatelessWidget { onSecondaryTap: () { final actionList = AppDisclosureActionSheet(onSelected: (action) => _handleAction(context, action)); actionList.show( - context, context, anchorDirection: AnchorDirection.bottomWithCenterAligned, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart index a2cd2edcac..cf66476ab8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart @@ -32,7 +32,7 @@ class ViewDisclosureButton extends StatelessWidget width: 26, onPressed: () { onTap(); - show(context, context); + show(context); }, icon: svg("editor/details", color: theme.iconColor), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index ed0a718f58..080211a8b7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -9,7 +9,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'item.dart'; -import 'package:async/async.dart'; class ViewSection extends StatelessWidget { final AppDataNotifier appData; 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 e8f0290123..83e577ec10 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -188,7 +188,6 @@ class DocumentShareButton extends StatelessWidget { }); }); actionList.show( - context, context, anchorDirection: AnchorDirection.bottomWithCenterAligned, anchorOffset: offset, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/color_picker.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/color_picker.dart index 793399989c..57299bd6cc 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/color_picker.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/color_picker.dart @@ -117,15 +117,6 @@ class _FlowyColorButtonState extends State { } void _showColorPicker() { - // FlowyPoppuWindow.show( - // context, - // size: Size(600, 200), - // child: MaterialPicker( - // pickerColor: const Color(0x00000000), - // onColorChanged: (color) => _changeColor(context, color), - // ), - // ); - final style = widget.controller.getSelectionStyle(); final values = style.values.where((v) => v.key == Attribute.background.key).map((v) => v.value); int initialColor = 0; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 5f8f94e1a2..0daca272b6 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -8,13 +8,13 @@ class GridSize { static double get footerHeight => 40 * scale; static double get leadingHeaderPadding => 30 * scale; static double get trailHeaderPadding => 140 * scale; - static double get headerContentPadding => 8 * scale; - static double get cellContentPadding => 8 * scale; + static double get headerContainerPadding => 0 * scale; + static double get cellContentPadding => 10 * scale; // static EdgeInsets get headerContentInsets => EdgeInsets.symmetric( - horizontal: GridSize.headerContentPadding, - vertical: GridSize.headerContentPadding, + horizontal: GridSize.headerContainerPadding, + vertical: GridSize.headerContainerPadding, ); static EdgeInsets get cellContentInsets => EdgeInsets.symmetric( horizontal: GridSize.cellContentPadding, @@ -23,8 +23,8 @@ class GridSize { static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( 0, - GridSize.headerContentPadding, - GridSize.headerContentPadding, - GridSize.headerContentPadding, + GridSize.headerContainerPadding, + GridSize.headerContainerPadding, + GridSize.headerContainerPadding, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 69e27a0fc4..7528c3c00a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -39,7 +39,7 @@ class _AddRowButton extends StatelessWidget { text: const FlowyText.medium('New row', fontSize: 12), hoverColor: theme.hover, onTap: () => context.read().add(const GridEvent.createRow()), - icon: svg("home/add"), + leftIcon: svg("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index e84640a584..a9fb91bb00 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -61,9 +61,9 @@ class GridHeader extends StatelessWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - const LeadingHeaderCell(), + const _HeaderLeading(), ...headers, - const TrailingHeaderCell(), + const _HeaderTrailing(), ], ), ); @@ -73,8 +73,8 @@ class GridHeader extends StatelessWidget { } } -class LeadingHeaderCell extends StatelessWidget { - const LeadingHeaderCell({Key? key}) : super(key: key); +class _HeaderLeading extends StatelessWidget { + const _HeaderLeading({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -84,8 +84,8 @@ class LeadingHeaderCell extends StatelessWidget { } } -class TrailingHeaderCell extends StatelessWidget { - const TrailingHeaderCell({Key? key}) : super(key: key); +class _HeaderTrailing extends StatelessWidget { + const _HeaderTrailing({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -112,7 +112,7 @@ class CreateColumnButton extends StatelessWidget { text: const FlowyText.medium('New column', fontSize: 12), hoverColor: theme.hover, onTap: () => context.read().add(const ColumnEvent.createColumn()), - icon: svg("home/add"), + leftIcon: svg("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index aacdcd251e..2f9b0b2fd2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,7 +1,10 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/widgets/pop_up_window.dart'; +import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -14,9 +17,31 @@ class HeaderCell extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( - text: FlowyText.medium(field.name, fontSize: 12), + text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(field.name, fontSize: 12)), hoverColor: theme.hover, - onTap: () {}, + onTap: () { + FlowyPoppuWindow.show( + context, + size: Size(300, 100), + child: Container( + color: Colors.red, + child: TextField( + decoration: InputDecoration(hintText: 'Please enter a text'), + onSubmitted: print, + ), + ), + ); + + // StyledDialog( + // child: SingleChildScrollView( + // child: Container( + // color: Colors.red, + // child: TextField(), + // ), + // ), + // ).show(context); + }, + rightIcon: svg("editor/details", color: theme.iconColor), ); } } 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 e74289d982..14b12d77bf 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart @@ -146,7 +146,7 @@ class _TrashPageState extends State { size: const Size(102, 30), child: FlowyButton( text: FlowyText.medium(LocaleKeys.trash_restoreAll.tr(), fontSize: 12), - icon: svg('editor/restore', color: theme.iconColor), + leftIcon: svg('editor/restore', color: theme.iconColor), hoverColor: theme.hover, onTap: () => context.read().add(const TrashEvent.restoreAll()), ), @@ -156,7 +156,7 @@ class _TrashPageState extends State { size: const Size(102, 30), child: FlowyButton( text: FlowyText.medium(LocaleKeys.trash_deleteAll.tr(), fontSize: 12), - icon: svg('editor/delete', color: theme.iconColor), + leftIcon: svg('editor/delete', color: theme.iconColor), hoverColor: theme.hover, onTap: () => context.read().add(const TrashEvent.deleteAll()), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart index 2c28b88660..239918994e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart @@ -112,7 +112,6 @@ class QuestionBubble extends StatelessWidget { }); }); actionList.show( - context, context, anchorDirection: AnchorDirection.topWithRightAligned, anchorOffset: const Offset(0, -10), diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart index 61caa84c2f..5c782d3ece 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart @@ -24,8 +24,8 @@ abstract class ActionList { FlowyOverlayDelegate? get delegate; void show( - BuildContext buildContext, - BuildContext anchorContext, { + BuildContext buildContext, { + BuildContext? anchorContext, AnchorDirection anchorDirection = AnchorDirection.bottomRight, Offset? anchorOffset, }) { @@ -47,7 +47,7 @@ abstract class ActionList { identifier: identifier, itemCount: widgets.length, itemBuilder: (context, index) => widgets[index], - anchorContext: anchorContext, + anchorContext: anchorContext ?? buildContext, anchorDirection: anchorDirection, width: maxWidth, height: widgets.length * (itemHeight + ActionListSizes.padding * 2), diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart index bea342747b..bad7eb2da6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart @@ -21,6 +21,7 @@ class FlowyPoppuWindow extends StatelessWidget { required Size size, }) async { final window = await getWindowInfo(); + FlowyOverlay.of(context).insertWithRect( widget: SizedBox.fromSize( size: size, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 84c2cddd82..4732374372 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -279,8 +279,11 @@ class FlowyOverlayState extends State { children.add(child); } - return Stack( - children: children..addAll(overlays), + return MaterialApp( + debugShowCheckedModeBanner: false, + home: Stack( + children: children..addAll(overlays), + ), ); } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart index 862f47b662..b83c454322 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart @@ -103,38 +103,4 @@ class ListOverlay extends StatelessWidget { style: style, ); } - - static void showWithRect( - BuildContext context, { - required BuildContext anchorContext, - required String identifier, - required IndexedWidgetBuilder itemBuilder, - int? itemCount, - ScrollController? controller, - double maxWidth = double.infinity, - double maxHeight = double.infinity, - required Offset anchorPosition, - required Size anchorSize, - AnchorDirection? anchorDirection, - FlowyOverlayDelegate? delegate, - OverlapBehaviour? overlapBehaviour, - FlowyOverlayStyle? style, - }) { - FlowyOverlay.of(context).insertWithRect( - widget: ListOverlay( - itemBuilder: itemBuilder, - itemCount: itemCount, - controller: controller, - width: maxWidth, - height: maxHeight, - ), - identifier: identifier, - anchorPosition: anchorPosition, - anchorSize: anchorSize, - anchorDirection: anchorDirection, - delegate: delegate, - overlapBehaviour: overlapBehaviour, - style: style, - ); - } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index b7d8ea4e88..dee66a8f11 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -8,14 +8,16 @@ class FlowyButton extends StatelessWidget { final Widget text; final VoidCallback? onTap; final EdgeInsets padding; - final Widget? icon; + final Widget? leftIcon; + final Widget? rightIcon; final Color hoverColor; const FlowyButton({ Key? key, required this.text, this.onTap, this.padding = const EdgeInsets.symmetric(horizontal: 3, vertical: 2), - this.icon, + this.leftIcon, + this.rightIcon, this.hoverColor = Colors.transparent, }) : super(key: key); @@ -33,13 +35,19 @@ class FlowyButton extends StatelessWidget { Widget _render() { List children = List.empty(growable: true); - if (icon != null) { - children.add(SizedBox.fromSize(size: const Size.square(16), child: icon!)); + if (leftIcon != null) { + children.add(SizedBox.fromSize(size: const Size.square(16), child: leftIcon!)); children.add(const HSpace(6)); } children.add(Align(child: text)); + if (rightIcon != null) { + children.add(const Spacer()); + children.add(SizedBox.fromSize(size: const Size.square(16), child: rightIcon!)); + children.add(const HSpace(6)); + } + return Padding( padding: padding, child: Row( From 2bbcfaf3cec3b9aecaa93d718259d20338aaa063 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 21 Mar 2022 23:13:11 +0800 Subject: [PATCH 055/179] chore: config edit pannel --- .../lib/workspace/application/appearance.dart | 1 - .../application/edit_pannel/edit_context.dart | 13 +--------- .../edit_pannel/edit_pannel_bloc.dart | 1 - .../workspace/application/home/home_bloc.dart | 8 +++---- .../presentation/home/home_layout.dart | 2 +- .../presentation/home/home_screen.dart | 21 +++++++++++----- .../grid/src/widgets/header/field_editor.dart | 1 + .../grid/src/widgets/header/header_cell.dart | 24 ++++++++++++------- .../widgets/edit_pannel/edit_pannel.dart | 13 ++++------ .../presentation/widgets/pop_up_window.dart | 1 - .../lib/src/flowy_overlay/flowy_overlay.dart | 11 +++++++++ 11 files changed, 54 insertions(+), 42 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart diff --git a/frontend/app_flowy/lib/workspace/application/appearance.dart b/frontend/app_flowy/lib/workspace/application/appearance.dart index ffd7e18c92..06473729a8 100644 --- a/frontend/app_flowy/lib/workspace/application/appearance.dart +++ b/frontend/app_flowy/lib/workspace/application/appearance.dart @@ -7,7 +7,6 @@ import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_setting.pb.dart'; import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:async/async.dart'; class AppearanceSettingModel extends ChangeNotifier with EquatableMixin { AppearanceSettings setting; diff --git a/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart b/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart index cd52bc7f11..571461b365 100644 --- a/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart +++ b/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart @@ -5,19 +5,8 @@ abstract class EditPannelContext extends Equatable { final String identifier; final String title; final Widget child; - const EditPannelContext( - {required this.child, required this.identifier, required this.title}); + const EditPannelContext({required this.child, required this.identifier, required this.title}); @override List get props => [identifier]; } - -class BlankEditPannelContext extends EditPannelContext { - const BlankEditPannelContext() - : super(child: const Text('Blank'), identifier: '1', title: ''); -} - -class CellEditPannelContext extends EditPannelContext { - const CellEditPannelContext() - : super(child: const Text('shit'), identifier: 'test', title: 'test'); -} diff --git a/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.dart index 0ae2e8326a..e1f2f5835d 100644 --- a/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/workspace/application/edit_pannel/edit_context.dart'; import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -// ignore: import_of_legacy_library_into_null_safe import 'package:flutter_bloc/flutter_bloc.dart'; part 'edit_pannel_bloc.freezed.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart b/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart index e4b0482989..5ed7ce959d 100644 --- a/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart @@ -12,10 +12,10 @@ class HomeBloc extends Bloc { emit(state.copyWith(isLoading: e.isLoading)); }, setEditPannel: (e) async { - emit(state.copyWith(editContext: some(e.editContext))); + emit(state.copyWith(pannelContext: some(e.editContext))); }, dismissEditPannel: (value) async { - emit(state.copyWith(editContext: none())); + emit(state.copyWith(pannelContext: none())); }, forceCollapse: (e) async { emit(state.copyWith(forceCollapse: e.forceCollapse)); @@ -43,12 +43,12 @@ class HomeState with _$HomeState { const factory HomeState({ required bool isLoading, required bool forceCollapse, - required Option editContext, + required Option pannelContext, }) = _HomeState; factory HomeState.initial() => HomeState( isLoading: false, forceCollapse: false, - editContext: none(), + pannelContext: none(), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/home_layout.dart b/frontend/app_flowy/lib/workspace/presentation/home/home_layout.dart index f0192a846b..0405279851 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_layout.dart @@ -20,7 +20,7 @@ class HomeLayout { HomeLayout(BuildContext context, BoxConstraints homeScreenConstraint, bool forceCollapse) { final homeBlocState = context.read().state; - showEditPannel = homeBlocState.editContext.isSome(); + showEditPannel = homeBlocState.pannelContext.isSome(); menuWidth = Sizes.sideBarMed; if (context.widthPx >= PageBreaks.desktop) { diff --git a/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart b/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart index 88ec0f5ad6..e9bb80dd30 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart @@ -126,13 +126,22 @@ class _HomeScreenState extends State { Widget _buildEditPannel({required HomeState homeState, required BuildContext context, required HomeLayout layout}) { final homeBloc = context.read(); - Widget editPannel = EditPannel( - context: homeState.editContext, - onEndEdit: () => homeBloc.add(const HomeEvent.dismissEditPannel()), + return BlocBuilder( + buildWhen: (previous, current) => previous.pannelContext != current.pannelContext, + builder: (context, state) { + return state.pannelContext.fold( + () => const SizedBox(), + (pannelContext) => FocusTraversalGroup( + child: RepaintBoundary( + child: EditPannel( + pannelContext: pannelContext, + onEndEdit: () => homeBloc.add(const HomeEvent.dismissEditPannel()), + ), + ), + ), + ); + }, ); - // editPannel = RepaintBoundary(child: editPannel); - // editPannel = FocusTraversalGroup(child: editPannel); - return editPannel; } Widget _layoutWidgets({ diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -0,0 +1 @@ + diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 2f9b0b2fd2..4e870ae27d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -4,7 +4,6 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -23,13 +22,7 @@ class HeaderCell extends StatelessWidget { FlowyPoppuWindow.show( context, size: Size(300, 100), - child: Container( - color: Colors.red, - child: TextField( - decoration: InputDecoration(hintText: 'Please enter a text'), - onSubmitted: print, - ), - ), + child: CusTextField(), ); // StyledDialog( @@ -46,6 +39,21 @@ class HeaderCell extends StatelessWidget { } } +class CusTextField extends StatelessWidget { + const CusTextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Container( + color: theme.bg3, + child: TextField( + decoration: InputDecoration(hintText: 'Please enter a text'), + onSubmitted: print, + )); + } +} + class HeaderCellContainer extends StatelessWidget { final HeaderCell child; final double width; diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/edit_pannel/edit_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/edit_pannel/edit_pannel.dart index b892a8e49d..f9e5e0e6b5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/edit_pannel/edit_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/edit_pannel/edit_pannel.dart @@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dar import 'package:app_flowy/workspace/application/edit_pannel/edit_context.dart'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/presentation/home/home_sizes.dart'; -import 'package:dartz/dartz.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/bar_title.dart'; import 'package:flowy_infra_ui/style_widget/close_button.dart'; @@ -11,15 +10,13 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; class EditPannel extends StatelessWidget { - late final EditPannelContext editContext; + final EditPannelContext pannelContext; final VoidCallback onEndEdit; - EditPannel({ + const EditPannel({ Key? key, - required Option context, + required this.pannelContext, required this.onEndEdit, - }) : super(key: key) { - editContext = context.fold(() => const BlankEditPannelContext(), (c) => c); - } + }) : super(key: key); @override Widget build(BuildContext context) { @@ -34,7 +31,7 @@ class EditPannel extends StatelessWidget { children: [ EditPannelTopBar(onClose: () => onEndEdit()), Expanded( - child: editContext.child, + child: pannelContext.child, ), ], ); diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart index bad7eb2da6..bea342747b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart @@ -21,7 +21,6 @@ class FlowyPoppuWindow extends StatelessWidget { required Size size, }) async { final window = await getWindowInfo(); - FlowyOverlay.of(context).insertWithRect( widget: SizedBox.fromSize( size: size, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 4732374372..11ec524ed4 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -279,6 +279,17 @@ class FlowyOverlayState extends State { children.add(child); } + // Try to fix there is no overlay for editabletext widget. e.g. TextField. + // // Check out the TextSelectionOverlay class in text_selection.dart. + // // ... + // // final OverlayState? overlay = Overlay.of(context, rootOverlay: true); + // // assert( + // // overlay != null, + // // 'No Overlay widget exists above $context.\n' + // // 'Usually the Navigator created by WidgetsApp provides the overlay. Perhaps your ' + // // 'app content was created above the Navigator with the WidgetsApp builder parameter.', + // // ); + // // ... return MaterialApp( debugShowCheckedModeBanner: false, home: Stack( From 188302d4ba5eda194dac82b1aa4bd623f07a6eb0 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 22 Mar 2022 20:51:15 +0800 Subject: [PATCH 056/179] chore: config field editor --- .../app_flowy/assets/images/grid/delete.svg | 6 + .../assets/images/grid/duplicate.svg | 4 + .../app_flowy/assets/images/grid/hide.svg | 4 + .../app_flowy/assets/images/grid/left.svg | 5 + .../app_flowy/assets/images/grid/right.svg | 5 + .../app_flowy/assets/translations/en.json | 9 + .../lib/startup/home_deps_resolver.dart | 15 +- .../lib/user/presentation/sign_in_screen.dart | 4 +- .../lib/user/presentation/sign_up_screen.dart | 6 +- .../grid/cell_bloc/cell_service.dart | 2 +- .../application/grid/column_bloc.dart | 42 ---- .../application/grid/column_service.dart | 1 - .../grid/field/field_edit_bloc.dart | 58 +++++ .../application/grid/field/field_service.dart | 1 + .../grid/field/grid_header_bloc.dart | 42 ++++ .../workspace/application/grid/prelude.dart | 9 +- .../application/grid/{ => row}/row_bloc.dart | 2 +- .../grid/{ => row}/row_listener.dart | 0 .../grid/{ => row}/row_service.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 5 + .../src/widgets/content/cell_builder.dart | 2 +- .../src/widgets/content/checkbox_cell.dart | 3 +- .../grid/src/widgets/content/date_cell.dart | 3 +- .../grid/src/widgets/content/number_cell.dart | 3 +- .../grid/src/widgets/content/text_cell.dart | 4 +- .../grid/src/widgets/header/field_editor.dart | 207 ++++++++++++++++++ .../grid/src/widgets/header/header.dart | 8 +- .../grid/src/widgets/header/header_cell.dart | 41 +--- .../presentation/widgets/pop_up_window.dart | 5 +- .../lib/src/flowy_overlay/flowy_overlay.dart | 2 + .../lib/src/flowy_overlay/list_overlay.dart | 39 ++-- .../src/flowy_overlay/overlay_container.dart | 30 +++ .../lib/style_widget/hover.dart | 17 +- .../lib/widget/rounded_input_field.dart | 109 +++++---- .../lib/widget/text_field_container.dart | 40 ---- frontend/app_flowy/pubspec.yaml | 1 + 36 files changed, 504 insertions(+), 232 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/delete.svg create mode 100644 frontend/app_flowy/assets/images/grid/duplicate.svg create mode 100644 frontend/app_flowy/assets/images/grid/hide.svg create mode 100644 frontend/app_flowy/assets/images/grid/left.svg create mode 100644 frontend/app_flowy/assets/images/grid/right.svg delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart rename frontend/app_flowy/lib/workspace/application/grid/{ => row}/row_bloc.dart (97%) rename frontend/app_flowy/lib/workspace/application/grid/{ => row}/row_listener.dart (100%) rename frontend/app_flowy/lib/workspace/application/grid/{ => row}/row_service.dart (93%) create mode 100644 frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart delete mode 100644 frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart diff --git a/frontend/app_flowy/assets/images/grid/delete.svg b/frontend/app_flowy/assets/images/grid/delete.svg new file mode 100644 index 0000000000..fcfbf2f6dd --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/delete.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/app_flowy/assets/images/grid/duplicate.svg b/frontend/app_flowy/assets/images/grid/duplicate.svg new file mode 100644 index 0000000000..f11048fd2f --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/duplicate.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/hide.svg b/frontend/app_flowy/assets/images/grid/hide.svg new file mode 100644 index 0000000000..dfb6dbb90c --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/hide.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/left.svg b/frontend/app_flowy/assets/images/grid/left.svg new file mode 100644 index 0000000000..0f771a3858 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/app_flowy/assets/images/grid/right.svg b/frontend/app_flowy/assets/images/grid/right.svg new file mode 100644 index 0000000000..7d738f4e69 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 7717e71229..27574db94e 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -141,5 +141,14 @@ "lightLabel": "Light Mode", "darkLabel": "Dark Mode" } + }, + "grid": { + "field": { + "hide": "Hide", + "insertLeft": "Insert Left", + "insertRight": "Insert Right", + "duplicate": "Duplicate", + "delete": "Delete" + } } } diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 2dcf6ca077..688c53ad2a 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -3,7 +3,7 @@ import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/row_listener.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_listener.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/view/prelude.dart'; @@ -101,10 +101,17 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam, void>( - (data, _) => ColumnBloc( + getIt.registerFactoryParam, void>( + (data, _) => GridHeaderBloc( data: GridColumnData(fields: data), - service: ColumnService(), + service: FieldService(), + ), + ); + + getIt.registerFactoryParam( + (field, _) => FieldEditBloc( + field: field, + service: FieldService(), ), ); diff --git a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart index f7afa0b4d3..8124241cf4 100644 --- a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart @@ -174,7 +174,7 @@ class PasswordTextField extends StatelessWidget { obscureHideIcon: svg("home/show"), hintText: LocaleKeys.signIn_passwordHint.tr(), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.passwordError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignInEvent.passwordChanged(value)), @@ -199,7 +199,7 @@ class EmailTextField extends StatelessWidget { hintText: LocaleKeys.signIn_emailHint.tr(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.emailError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignInEvent.emailChanged(value)), diff --git a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart index 931ccff516..06d4db6da2 100644 --- a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart @@ -139,7 +139,7 @@ class PasswordTextField extends StatelessWidget { style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), hintText: LocaleKeys.signUp_passwordHint.tr(), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.passwordError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignUpEvent.passwordChanged(value)), @@ -167,7 +167,7 @@ class RepeatPasswordTextField extends StatelessWidget { style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), hintText: LocaleKeys.signUp_repeatPasswordHint.tr(), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.repeatPasswordError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignUpEvent.repeatPasswordChanged(value)), @@ -192,7 +192,7 @@ class EmailTextField extends StatelessWidget { hintText: LocaleKeys.signUp_emailHint.tr(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.emailError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignUpEvent.emailChanged(value)), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index 44cf86e5d2..79b4d2cf52 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart deleted file mode 100644 index 39badc922a..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'column_service.dart'; -import 'data.dart'; - -part 'column_bloc.freezed.dart'; - -class ColumnBloc extends Bloc { - final ColumnService service; - final GridColumnData data; - - ColumnBloc({required this.data, required this.service}) : super(ColumnState.initial(data.fields)) { - on( - (event, emit) async { - await event.map( - initial: (_InitialColumn value) async {}, - createColumn: (_CreateColumn value) {}, - ); - }, - ); - } - - @override - Future close() async { - return super.close(); - } -} - -@freezed -abstract class ColumnEvent with _$ColumnEvent { - const factory ColumnEvent.initial() = _InitialColumn; - const factory ColumnEvent.createColumn() = _CreateColumn; -} - -@freezed -abstract class ColumnState with _$ColumnState { - const factory ColumnState({required List fields}) = _ColumnState; - - factory ColumnState.initial(List fields) => ColumnState(fields: fields); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_service.dart b/frontend/app_flowy/lib/workspace/application/grid/column_service.dart deleted file mode 100644 index c074dcf616..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/column_service.dart +++ /dev/null @@ -1 +0,0 @@ -class ColumnService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart new file mode 100644 index 0000000000..2d4aea16da --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart @@ -0,0 +1,58 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'field_edit_bloc.freezed.dart'; + +class FieldEditBloc extends Bloc { + final FieldService service; + + FieldEditBloc({required Field field, required this.service}) : super(FieldEditState.initial(field)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) {}, + createField: (_CreateField value) {}, + updateFieldName: (_UpdateFieldName value) { + // + }, + hideField: (_HideField value) {}, + deleteField: (_DeleteField value) {}, + insertField: (_InsertField value) {}, + duplicateField: (_DuplicateField value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class FieldEditEvent with _$FieldEditEvent { + const factory FieldEditEvent.initial() = _InitialField; + const factory FieldEditEvent.createField() = _CreateField; + const factory FieldEditEvent.updateFieldName(String name) = _UpdateFieldName; + const factory FieldEditEvent.hideField() = _HideField; + const factory FieldEditEvent.duplicateField() = _DuplicateField; + const factory FieldEditEvent.insertField({required bool onLeft}) = _InsertField; + const factory FieldEditEvent.deleteField() = _DeleteField; +} + +@freezed +class FieldEditState with _$FieldEditState { + const factory FieldEditState({ + required Field field, + required String errorText, + }) = _FieldEditState; + + factory FieldEditState.initial(Field field) => FieldEditState( + field: field, + errorText: '', + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart new file mode 100644 index 0000000000..48d4aa21bd --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -0,0 +1 @@ +class FieldService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart new file mode 100644 index 0000000000..fd22d7a505 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -0,0 +1,42 @@ +import 'package:app_flowy/workspace/application/grid/data.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'grid_header_bloc.freezed.dart'; + +class GridHeaderBloc extends Bloc { + final FieldService service; + final GridColumnData data; + + GridHeaderBloc({required this.data, required this.service}) : super(GridHeaderState.initial(data.fields)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialHeader value) async {}, + createField: (_CreateField value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class GridHeaderEvent with _$GridHeaderEvent { + const factory GridHeaderEvent.initial() = _InitialHeader; + const factory GridHeaderEvent.createField() = _CreateField; +} + +@freezed +class GridHeaderState with _$GridHeaderState { + const factory GridHeaderState({required List fields}) = _GridHeaderState; + + factory GridHeaderState.initial(List fields) => GridHeaderState(fields: fields); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index d28df04c62..3190ced75d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -1,10 +1,11 @@ export 'grid_bloc.dart'; -export 'row_bloc.dart'; -export 'row_service.dart'; +export 'row/row_bloc.dart'; +export 'row/row_service.dart'; export 'grid_service.dart'; export 'data.dart'; -export 'column_service.dart'; -export 'column_bloc.dart'; +export 'field/field_service.dart'; +export 'field/grid_header_bloc.dart'; +export 'field/field_edit_bloc.dart'; export 'cell_bloc/text_cell_bloc.dart'; export 'cell_bloc/number_cell_bloc.dart'; export 'cell_bloc/selection_cell_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart similarity index 97% rename from frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 67fcc5cbc2..a30bea39ee 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,9 +1,9 @@ +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'grid_service.dart'; import 'row_listener.dart'; import 'row_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/application/grid/row_listener.dart rename to frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/application/grid/row_service.dart rename to frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 013ae3fb1c..6819a9a40e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -3,7 +3,7 @@ import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'grid_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; class RowService { final GridRowData rowData; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 0daca272b6..e94507ab52 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -21,6 +21,11 @@ class GridSize { vertical: GridSize.cellContentPadding, ); + static EdgeInsets get fieldContentInsets => EdgeInsets.symmetric( + horizontal: GridSize.cellContentPadding, + vertical: GridSize.cellContentPadding, + ); + static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( 0, GridSize.headerContainerPadding, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 187a81c1bc..7aa412589e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index eec381914a..2f067ab1fa 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index 5d9f452c78..5d69783fc5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index ea3f70fed3..0402b85b12 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 937c5d84ab..d3a9e88c2e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,8 +1,6 @@ import 'dart:async'; - import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index 8b13789179..531d83a1f3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -1 +1,208 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +class FieldEditor extends StatelessWidget { + final Field field; + const FieldEditor({required this.field, Key? key}) : super(key: key); + + static void show(BuildContext context, Field field) { + final editor = FieldEditor(field: field); + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer(child: editor), + identifier: editor.identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomWithLeftAligned, + style: FlowyOverlayStyle(blur: false), + ); + } + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocProvider( + create: (context) => getIt(param1: field)..add(const FieldEditEvent.initial()), + child: Container( + color: theme.surface, + constraints: BoxConstraints.loose(const Size(300, 200)), + child: SingleChildScrollView( + child: Column(children: [ + const FieldNameTextField(), + // FieldTypeSwitcher(), + const VSpace(10), + FieldOperationList( + onTap: () { + FlowyOverlay.of(context).remove(identifier()); + }, + ), + ]), + ), + ), + ); + } + + String identifier() { + return toString(); + } +} + +class FieldNameTextField extends StatelessWidget { + const FieldNameTextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocBuilder( + buildWhen: ((previous, current) => previous.field.name == current.field.name), + builder: (context, state) { + return RoundedInputField( + height: 36, + style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), + initialValue: state.field.name, + normalBorderColor: theme.shader4, + errorBorderColor: theme.red, + focusBorderColor: theme.main1, + cursorColor: theme.main1, + errorText: state.errorText, + onChanged: (value) { + context.read().add(FieldEditEvent.updateFieldName(value)); + }, + ); + }, + ); + } +} + +class FieldTypeSwitcher extends StatelessWidget { + const FieldTypeSwitcher({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return FlowyButton( + text: FlowyText.medium(context.read().state.field.name, fontSize: 12), + hoverColor: theme.hover, + onTap: () {}, + leftIcon: svg("editor/details", color: theme.iconColor), + ); + } +} + +class FieldOperationList extends StatelessWidget { + final VoidCallback onTap; + const FieldOperationList({required this.onTap, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final children = FieldAction.values + .map((action) => FieldActionItem( + action: action, + onTap: onTap, + )) + .toList(); + return GridView( + // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.0, + mainAxisSpacing: 8, + ), + children: children, + ); + } +} + +class FieldActionItem extends StatelessWidget { + final VoidCallback onTap; + final FieldAction action; + const FieldActionItem({required this.action, required this.onTap, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: FlowyText.medium(action.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + action.run(context); + onTap(); + }, + leftIcon: svg(action.iconName(), color: theme.iconColor), + ); + } +} + +enum FieldAction { + hide, + insertLeft, + duplicate, + insertRight, + delete, +} + +extension _FieldActionExtension on FieldAction { + String iconName() { + switch (this) { + case FieldAction.hide: + return 'grid/hide'; + case FieldAction.insertLeft: + return 'grid/left'; + case FieldAction.insertRight: + return 'grid/right'; + case FieldAction.duplicate: + return 'grid/duplicate'; + case FieldAction.delete: + return 'grid/delete'; + } + } + + String title() { + switch (this) { + case FieldAction.hide: + return LocaleKeys.grid_field_hide.tr(); + case FieldAction.insertLeft: + return LocaleKeys.grid_field_insertLeft.tr(); + case FieldAction.insertRight: + return LocaleKeys.grid_field_insertRight.tr(); + case FieldAction.duplicate: + return LocaleKeys.grid_field_duplicate.tr(); + case FieldAction.delete: + return LocaleKeys.grid_field_delete.tr(); + } + } + + void run(BuildContext context) { + final bloc = context.read(); + + switch (this) { + case FieldAction.hide: + bloc.add(const FieldEditEvent.hideField()); + break; + case FieldAction.insertLeft: + bloc.add(const FieldEditEvent.insertField(onLeft: true)); + break; + case FieldAction.insertRight: + bloc.add(const FieldEditEvent.insertField(onLeft: false)); + break; + case FieldAction.duplicate: + bloc.add(const FieldEditEvent.duplicateField()); + break; + case FieldAction.delete: + bloc.add(const FieldEditEvent.deleteField()); + break; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index a9fb91bb00..40f6a3e3b0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/column_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -44,8 +44,8 @@ class GridHeader extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return BlocProvider( - create: (context) => getIt(param1: fields)..add(const ColumnEvent.initial()), - child: BlocBuilder( + create: (context) => getIt(param1: fields)..add(const GridHeaderEvent.initial()), + child: BlocBuilder( builder: (context, state) { final headers = state.fields .map( @@ -111,7 +111,7 @@ class CreateColumnButton extends StatelessWidget { return FlowyButton( text: const FlowyText.medium('New column', fontSize: 12), hoverColor: theme.hover, - onTap: () => context.read().add(const ColumnEvent.createColumn()), + onTap: () => context.read().add(const GridHeaderEvent.createField()), leftIcon: svg("home/add"), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 4e870ae27d..fa8a3692c5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/widgets/pop_up_window.dart'; + import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; @@ -8,6 +8,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'field_editor.dart'; + class HeaderCell extends StatelessWidget { final Field field; const HeaderCell(this.field, {Key? key}) : super(key: key); @@ -16,44 +18,17 @@ class HeaderCell extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( - text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(field.name, fontSize: 12)), + text: Padding( + padding: GridSize.cellContentInsets, + child: FlowyText.medium(field.name, fontSize: 12), + ), hoverColor: theme.hover, - onTap: () { - FlowyPoppuWindow.show( - context, - size: Size(300, 100), - child: CusTextField(), - ); - - // StyledDialog( - // child: SingleChildScrollView( - // child: Container( - // color: Colors.red, - // child: TextField(), - // ), - // ), - // ).show(context); - }, + onTap: () => FieldEditor.show(context, field), rightIcon: svg("editor/details", color: theme.iconColor), ); } } -class CusTextField extends StatelessWidget { - const CusTextField({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return Container( - color: theme.bg3, - child: TextField( - decoration: InputDecoration(hintText: 'Please enter a text'), - onSubmitted: print, - )); - } -} - class HeaderCellContainer extends StatelessWidget { final HeaderCell child; final double width; diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart index bea342747b..1803257672 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart @@ -22,10 +22,7 @@ class FlowyPoppuWindow extends StatelessWidget { }) async { final window = await getWindowInfo(); FlowyOverlay.of(context).insertWithRect( - widget: SizedBox.fromSize( - size: size, - child: FlowyPoppuWindow(child: child), - ), + widget: FlowyPoppuWindow(child: child), identifier: 'FlowyPoppuWindow', anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), anchorSize: window.frame.size, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 11ec524ed4..26760dc411 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -5,6 +5,8 @@ import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart'; import 'package:flutter/material.dart'; import 'dart:ui'; +export './overlay_container.dart'; + /// Specifies how overlay are anchored to the SourceWidget enum AnchorDirection { // Corner aligned with a corner of the SourceWidget diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart index b83c454322..6c0a4019d1 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart @@ -35,36 +35,29 @@ class ListOverlay extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = context.watch(); const padding = EdgeInsets.symmetric(horizontal: 6, vertical: 6); double totalHeight = height + padding.vertical; if (footer != null) { totalHeight = totalHeight + footer!.height + footer!.padding.vertical; } - return Material( - type: MaterialType.transparency, - child: Container( - decoration: FlowyDecoration.decoration(theme.surface, theme.shadowColor.withOpacity(0.1)), - constraints: BoxConstraints.tight(Size(width, totalHeight)), - child: Padding( - padding: padding, - child: Column( - children: [ - ListView.builder( - shrinkWrap: true, - itemBuilder: itemBuilder, - itemCount: itemCount, - controller: controller, - ), - if (footer != null) - Padding( - padding: footer!.padding, - child: footer!.widget, - ), - ], + return OverlayContainer( + constraints: BoxConstraints.tight(Size(width, totalHeight)), + padding: padding, + child: Column( + children: [ + ListView.builder( + shrinkWrap: true, + itemBuilder: itemBuilder, + itemCount: itemCount, + controller: controller, ), - ), + if (footer != null) + Padding( + padding: footer!.padding, + child: footer!.widget, + ), + ], ), ); } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart new file mode 100644 index 0000000000..bee123d248 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart @@ -0,0 +1,30 @@ +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/decoration.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class OverlayContainer extends StatelessWidget { + final Widget child; + final BoxConstraints? constraints; + final EdgeInsets padding; + const OverlayContainer({ + required this.child, + this.constraints, + this.padding = const EdgeInsets.all(12), + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Material( + type: MaterialType.transparency, + child: Container( + padding: padding, + decoration: FlowyDecoration.decoration(theme.surface, theme.shadowColor.withOpacity(0.1)), + constraints: constraints, + child: child, + ), + ); + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index a85867e456..b19578fe54 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flowy_infra/time/duration.dart'; typedef HoverBuilder = Widget Function(BuildContext context, bool onHover); - typedef IsOnSelected = bool Function(); class FlowyHover extends StatefulWidget { @@ -29,23 +28,20 @@ class _FlowyHoverState extends State { Widget build(BuildContext context) { return MouseRegion( cursor: SystemMouseCursors.click, - onEnter: (p) => setOnHover(true), - onExit: (p) => setOnHover(false), + onEnter: (p) => setState(() => _onHover = true), + onExit: (p) => setState(() => _onHover = false), child: render(), ); } - void setOnHover(bool value) => setState(() => _onHover = value); - Widget render() { var showHover = _onHover; - - if (showHover == false && widget.isOnSelected != null) { + if (!showHover && widget.isOnSelected != null) { showHover = widget.isOnSelected!(); } if (showHover) { - return FlowyHoverBackground( + return FlowyHoverContainer( config: widget.config, child: widget.builder(context, _onHover), ); @@ -68,12 +64,11 @@ class HoverDisplayConfig { required this.hoverColor}); } -class FlowyHoverBackground extends StatelessWidget { +class FlowyHoverContainer extends StatelessWidget { final HoverDisplayConfig config; - final Widget child; - const FlowyHoverBackground({ + const FlowyHoverContainer({ Key? key, required this.child, required this.config, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index e6e9684854..0cd2265cce 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -1,85 +1,105 @@ import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; -import 'package:flowy_infra_ui/widget/text_field_container.dart'; import 'package:flutter/material.dart'; import 'package:flowy_infra/time/duration.dart'; -// ignore: must_be_immutable class RoundedInputField extends StatefulWidget { final String? hintText; - final IconData? icon; final bool obscureText; final Widget? obscureIcon; final Widget? obscureHideIcon; final Color normalBorderColor; - final Color highlightBorderColor; + final Color errorBorderColor; final Color cursorColor; + final Color? focusBorderColor; final String errorText; final TextStyle style; final ValueChanged? onChanged; final String? initialValue; - late bool enableObscure; - var _text = ""; + final EdgeInsets margin; + final EdgeInsets padding; + final EdgeInsets contentPadding; + final double height; - RoundedInputField({ + const RoundedInputField({ Key? key, this.hintText, this.errorText = "", this.initialValue, - this.icon, this.obscureText = false, this.obscureIcon, this.obscureHideIcon, this.onChanged, this.normalBorderColor = Colors.transparent, - this.highlightBorderColor = Colors.transparent, + this.errorBorderColor = Colors.transparent, + this.focusBorderColor, this.cursorColor = Colors.black, this.style = const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), - }) : super(key: key) { - enableObscure = obscureText; - } + this.margin = EdgeInsets.zero, + this.padding = EdgeInsets.zero, + this.contentPadding = const EdgeInsets.symmetric(horizontal: 10), + this.height = 48, + }) : super(key: key); @override State createState() => _RoundedInputFieldState(); } class _RoundedInputFieldState extends State { + String inputText = ""; + bool obscuteText = false; + + @override + void initState() { + obscuteText = widget.obscureText; + super.initState(); + } + @override Widget build(BuildContext context) { - final Icon? newIcon = widget.icon == null - ? null - : Icon( - widget.icon!, - color: const Color(0xFF6F35A5), - ); - var borderColor = widget.normalBorderColor; + var focusBorderColor = widget.focusBorderColor ?? borderColor; + if (widget.errorText.isNotEmpty) { - borderColor = widget.highlightBorderColor; + borderColor = widget.errorBorderColor; + focusBorderColor = borderColor; } List children = [ - TextFieldContainer( - height: 48, - borderRadius: Corners.s10Border, - borderColor: borderColor, + Container( + margin: widget.margin, + padding: widget.padding, + height: widget.height, child: TextFormField( initialValue: widget.initialValue, onChanged: (value) { - widget._text = value; + inputText = value; if (widget.onChanged != null) { widget.onChanged!(value); } setState(() {}); }, cursorColor: widget.cursorColor, - obscureText: widget.enableObscure, + obscureText: obscuteText, decoration: InputDecoration( - icon: newIcon, + contentPadding: widget.contentPadding, hintText: widget.hintText, hintStyle: TextStyle(color: widget.normalBorderColor), - border: InputBorder.none, - suffixIcon: suffixIcon(), + border: OutlineInputBorder( + borderSide: BorderSide( + color: borderColor, + width: 1.0, + ), + borderRadius: Corners.s10Border, + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: focusBorderColor, + width: 1.0, + ), + borderRadius: Corners.s10Border, + ), + suffixIcon: obscureIcon(), ), ), ), @@ -100,39 +120,32 @@ class _RoundedInputFieldState extends State { return AnimatedSize( duration: .4.seconds, curve: Curves.easeInOut, - child: Column( - children: children, - ), + child: Column(children: children), ); } - Widget? suffixIcon() { + Widget? obscureIcon() { if (widget.obscureText == false) { return null; } - if (widget._text.isEmpty) { - return SizedBox.fromSize(size: const Size.square(16)); + const double iconWidth = 16; + if (inputText.isEmpty) { + return SizedBox.fromSize(size: const Size.square(iconWidth)); } + assert(widget.obscureIcon != null && widget.obscureHideIcon != null); Widget? icon; - if (widget.obscureText == true) { - assert(widget.obscureIcon != null && widget.obscureHideIcon != null); - if (widget.enableObscure) { - icon = widget.obscureIcon!; - } else { - icon = widget.obscureHideIcon!; - } - } - - if (icon == null) { - return null; + if (obscuteText) { + icon = widget.obscureIcon!; + } else { + icon = widget.obscureHideIcon!; } return RoundedImageButton( - size: 16, + size: iconWidth, press: () { - widget.enableObscure = !widget.enableObscure; + obscuteText = !obscuteText; setState(() {}); }, child: icon, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart deleted file mode 100644 index 7c1bf131a1..0000000000 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -class TextFieldContainer extends StatelessWidget { - final Widget child; - final BorderRadius borderRadius; - final Color borderColor; - final double? height; - final double? width; - const TextFieldContainer({ - Key? key, - required this.child, - this.borderRadius = BorderRadius.zero, - this.borderColor = Colors.white, - this.height, - this.width, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - margin: const EdgeInsets.symmetric(vertical: 10), - padding: const EdgeInsets.symmetric(horizontal: 15), - height: height, - width: width, - decoration: BoxDecoration( - border: Border.all(color: borderColor), - color: Colors.white, - borderRadius: borderRadius, - ), - child: Align(alignment: Alignment.center, child: child), - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(DiagnosticsProperty('child', child)); - } -} diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 41ee902083..61b69b45f1 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -111,6 +111,7 @@ flutter: - assets/images/ - assets/images/home/ - assets/images/editor/ + - assets/images/grid/ - assets/translations/ # - images/a_dot_ham.jpeg From 694963a47de1ea1cfc77cd4302524d7aaa828268 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 23 Mar 2022 22:10:31 +0800 Subject: [PATCH 057/179] chore: add update field and create field handler --- .../lib/startup/home_deps_resolver.dart | 6 +- .../workspace/application/app/app_bloc.dart | 2 +- .../application/app/app_listener.dart | 2 +- .../grid/field/grid_header_bloc.dart | 6 +- .../workspace/application/grid/grid_bloc.dart | 66 +++- .../application/grid/grid_block_service.dart | 49 +-- .../application/grid/grid_listenr.dart | 49 ++- .../application/trash/trash_bloc.dart | 2 +- .../application/trash/trash_listener.dart | 2 +- .../plugins/grid/src/grid_page.dart | 34 +- .../grid/src/widgets/header/header.dart | 49 +-- .../grid/src/widgets/header/header_cell.dart | 27 +- .../dart_event/flowy-grid/dart_event.dart | 34 ++ .../flowy-error-code/code.pbenum.dart | 14 +- .../flowy-error-code/code.pbjson.dart | 12 +- .../flowy-grid-data-model/grid.pb.dart | 104 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 16 + .../flowy-grid-data-model/meta.pb.dart | 128 ++++--- .../flowy-grid-data-model/meta.pbjson.dart | 21 +- .../flowy-grid/checkbox_description.pb.dart | 26 +- .../checkbox_description.pbjson.dart | 10 +- .../flowy-grid/checkbox_type_option.pb.dart | 58 +++ .../checkbox_type_option.pbenum.dart | 7 + .../checkbox_type_option.pbjson.dart | 20 + .../checkbox_type_option.pbserver.dart | 9 + .../flowy-grid/dart_notification.pbenum.dart | 8 +- .../flowy-grid/dart_notification.pbjson.dart | 6 +- .../flowy-grid/date_type_option.pb.dart | 76 ++++ .../flowy-grid/date_type_option.pbenum.dart | 45 +++ .../flowy-grid/date_type_option.pbjson.dart | 45 +++ .../flowy-grid/date_type_option.pbserver.dart | 9 + .../protobuf/flowy-grid/event_map.pbenum.dart | 10 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 10 +- .../flowy-grid/number_type_option.pb.dart | 118 ++++++ .../flowy-grid/number_type_option.pbenum.dart | 30 ++ .../flowy-grid/number_type_option.pbjson.dart | 37 ++ .../number_type_option.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 8 +- .../flowy-grid/selection_type_option.pb.dart | 196 ++++++++++ .../selection_type_option.pbenum.dart | 7 + .../selection_type_option.pbjson.dart | 44 +++ .../selection_type_option.pbserver.dart | 9 + .../flowy-grid/text_description.pb.dart | 26 +- .../flowy-grid/text_description.pbjson.dart | 10 +- frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- .../flowy-grid/src/dart_notification.rs | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 54 ++- frontend/rust-lib/flowy-grid/src/event_map.rs | 14 +- frontend/rust-lib/flowy-grid/src/macros.rs | 2 +- ...description.rs => checkbox_type_option.rs} | 42 +- .../src/protobuf/model/dart_notification.rs | 20 +- ...ate_description.rs => date_type_option.rs} | 50 +-- .../src/protobuf/model/event_map.rs | 27 +- .../flowy-grid/src/protobuf/model/mod.rs | 16 +- ...r_description.rs => number_type_option.rs} | 58 +-- ...escription.rs => selection_type_option.rs} | 96 ++--- .../src/protobuf/model/text_description.rs | 42 +- ...ption.proto => checkbox_type_option.proto} | 2 +- .../protobuf/proto/dart_notification.proto | 4 +- ...scription.proto => date_type_option.proto} | 2 +- .../src/protobuf/proto/event_map.proto | 8 +- ...ription.proto => number_type_option.proto} | 2 +- ...tion.proto => selection_type_option.proto} | 4 +- .../src/protobuf/proto/text_description.proto | 2 +- .../src/services/block_meta_editor.rs | 9 +- .../src/services/cell/builder/mod.rs | 137 ------- .../src/services/cell/description/mod.rs | 11 - .../flowy-grid/src/services/cell/mod.rs | 5 - .../src/services/field/field_builder.rs | 2 +- .../flowy-grid/src/services/field/mod.rs | 2 + .../type_options/checkbox_type_option.rs} | 30 +- .../type_options/date_type_option.rs} | 40 +- .../src/services/field/type_options/mod.rs | 11 + .../type_options/number_type_option.rs} | 180 +++++---- .../type_options/selection_type_option.rs} | 55 ++- .../type_options}/text_description.rs | 20 +- .../flowy-grid/src/services/grid_editor.rs | 13 +- .../rust-lib/flowy-grid/src/services/mod.rs | 1 - .../src/services/row/cell_data_serde.rs | 26 +- frontend/rust-lib/flowy-grid/src/util.rs | 1 - .../flowy-grid/tests/grid/grid_test.rs | 59 ++- .../rust-lib/flowy-grid/tests/grid/script.rs | 74 +++- shared-lib/flowy-error-code/src/code.rs | 18 +- .../src/protobuf/model/code.rs | 35 +- .../src/protobuf/proto/code.proto | 10 +- .../src/entities/grid.rs | 21 + .../src/entities/meta.rs | 21 +- .../flowy-grid-data-model/src/parser/grid.rs | 82 ---- .../src/parser/grid_params.rs | 116 ++++++ .../flowy-grid-data-model/src/parser/id.rs | 18 - .../src/parser/id_parser.rs | 22 ++ .../flowy-grid-data-model/src/parser/mod.rs | 8 +- .../src/protobuf/model/grid.rs | 361 +++++++++++++++++- .../src/protobuf/model/meta.rs | 217 ++++++----- .../src/protobuf/proto/grid.proto | 6 + .../src/protobuf/proto/meta.proto | 17 +- .../src/client_grid/grid_meta_pad.rs | 51 ++- 97 files changed, 2554 insertions(+), 1032 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbserver.dart rename frontend/rust-lib/flowy-grid/src/protobuf/model/{checkbox_description.rs => checkbox_type_option.rs} (82%) rename frontend/rust-lib/flowy-grid/src/protobuf/model/{date_description.rs => date_type_option.rs} (87%) rename frontend/rust-lib/flowy-grid/src/protobuf/model/{number_description.rs => number_type_option.rs} (88%) rename frontend/rust-lib/flowy-grid/src/protobuf/model/{selection_description.rs => selection_type_option.rs} (87%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{checkbox_description.proto => checkbox_type_option.proto} (61%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{date_description.proto => date_type_option.proto} (89%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{number_description.proto => number_type_option.proto} (88%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{selection_description.proto => selection_type_option.proto} (78%) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/mod.rs rename frontend/rust-lib/flowy-grid/src/services/{cell/description/checkbox_description.rs => field/type_options/checkbox_type_option.rs} (69%) rename frontend/rust-lib/flowy-grid/src/services/{cell/description/date_description.rs => field/type_options/date_type_option.rs} (87%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs rename frontend/rust-lib/flowy-grid/src/services/{cell/description/number_description.rs => field/type_options/number_type_option.rs} (86%) rename frontend/rust-lib/flowy-grid/src/services/{cell/description/selection_description.rs => field/type_options/selection_type_option.rs} (71%) rename frontend/rust-lib/flowy-grid/src/services/{cell/description => field/type_options}/text_description.rs (60%) delete mode 100644 shared-lib/flowy-grid-data-model/src/parser/grid.rs create mode 100644 shared-lib/flowy-grid-data-model/src/parser/grid_params.rs delete mode 100644 shared-lib/flowy-grid-data-model/src/parser/id.rs create mode 100644 shared-lib/flowy-grid-data-model/src/parser/id_parser.rs diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 688c53ad2a..5c4fc6267f 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -101,9 +101,9 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam, void>( - (data, _) => GridHeaderBloc( - data: GridColumnData(fields: data), + getIt.registerFactoryParam>( + (gridId, fields) => GridHeaderBloc( + data: GridColumnData(fields: fields), service: FieldService(), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart index 5175fe2396..73192436bf 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart @@ -19,7 +19,7 @@ class AppBloc extends Bloc { AppBloc({required this.app, required this.service, required this.listener}) : super(AppState.initial(app)) { on((event, emit) async { await event.map(initial: (e) async { - listener.startListening( + listener.start( viewsChanged: _handleViewsChanged, appUpdated: (app) => add(AppEvent.appDidUpdate(app)), ); diff --git a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart index 8f0ff7cb23..3d9bbbc65c 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart @@ -24,7 +24,7 @@ class AppListener { required this.appId, }); - void startListening({ViewsDidChangeCallback? viewsChanged, AppDidUpdateCallback? appUpdated}) { + void start({ViewsDidChangeCallback? viewsChanged, AppDidUpdateCallback? appUpdated}) { _viewsChanged = viewsChanged; _updated = appUpdated; _parser = FolderNotificationParser(id: appId, callback: _bservableCallback); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart index fd22d7a505..f4c7459337 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -9,9 +9,11 @@ part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc { final FieldService service; - final GridColumnData data; - GridHeaderBloc({required this.data, required this.service}) : super(GridHeaderState.initial(data.fields)) { + GridHeaderBloc({ + required GridColumnData data, + required this.service, + }) : super(GridHeaderState.initial(data.fields)) { on( (event, emit) async { await event.map( 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 fd2fefbac5..63a2a19ec7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -19,13 +19,13 @@ class GridBloc extends Bloc { late GridBlockService _blockService; GridBloc({required this.view, required this.service}) : super(GridState.initial()) { - _gridListener = GridListener(); + _gridListener = GridListener(gridId: view.id); on( (event, emit) async { await event.map( initial: (InitialGrid value) async { - await _loadGrid(emit); + await _initGrid(emit); }, createRow: (_CreateRow value) { service.createRow(gridId: view.id); @@ -36,6 +36,9 @@ class GridBloc extends Bloc { rowsDidUpdate: (_RowsDidUpdate value) { emit(state.copyWith(rows: value.rows)); }, + fieldsDidUpdate: (_FieldsDidUpdate value) { + emit(state.copyWith(fields: value.fields)); + }, ); }, ); @@ -48,26 +51,20 @@ class GridBloc extends Bloc { return super.close(); } - Future _initGridBlockService(Grid grid, List fields) async { - _blockService = GridBlockService( - gridId: grid.id, - fields: fields, - blockOrders: grid.blockOrders, - ); - - _blockService.rowsUpdateNotifier.addPublishListener((result) { + Future _initGrid(Emitter emit) async { + _gridListener.fieldsUpdateNotifier.addPublishListener((result) { result.fold( - (rows) => add(GridEvent.rowsDidUpdate(rows)), - (err) => Log.error('$err'), + (fields) => add(GridEvent.fieldsDidUpdate(fields)), + (err) => Log.error(err), ); }); - _gridListener.start(); + + await _loadGrid(emit); } Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); - return Future( () => result.fold( (grid) async => await _loadFields(grid, emit), @@ -81,10 +78,10 @@ class GridBloc extends Bloc { return Future( () => result.fold( (fields) { - _initGridBlockService(grid, fields.items); + _initGridBlockService(grid); emit(state.copyWith( grid: Some(grid), - fields: Some(fields.items), + fields: fields.items, loadingState: GridLoadingState.finish(left(unit)), )); }, @@ -92,6 +89,38 @@ class GridBloc extends Bloc { ), ); } + + Future _initGridBlockService(Grid grid) async { + _blockService = GridBlockService( + gridId: grid.id, + blockOrders: grid.blockOrders, + ); + + _blockService.blocksUpdateNotifier.addPublishListener((result) { + result.fold( + (blockMap) => add(GridEvent.rowsDidUpdate(_buildRows(blockMap))), + (err) => Log.error('$err'), + ); + }); + + _gridListener.start(); + } + + List _buildRows(GridBlockMap blockMap) { + List rows = []; + blockMap.forEach((_, GridBlock gridBlock) { + rows.addAll(gridBlock.rowOrders.map( + (rowOrder) => GridRowData( + gridId: view.id, + fields: state.fields, + blockId: gridBlock.id, + rowId: rowOrder.rowId, + height: rowOrder.height.toDouble(), + ), + )); + }); + return rows; + } } @freezed @@ -102,20 +131,21 @@ abstract class GridEvent with _$GridEvent { const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; const factory GridEvent.rowsDidUpdate(List rows) = _RowsDidUpdate; + const factory GridEvent.fieldsDidUpdate(List fields) = _FieldsDidUpdate; } @freezed abstract class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, - required Option> fields, + required List fields, required List rows, required Option grid, }) = _GridState; factory GridState.initial() => GridState( loadingState: const _Loading(), - fields: none(), + fields: [], rows: [], grid: none(), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index f84278399c..151b587d16 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -11,51 +11,34 @@ import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -import 'grid_service.dart'; -typedef RowsUpdateNotifierValue = Either, FlowyError>; +typedef GridBlockMap = LinkedHashMap; +typedef BlocksUpdateNotifierValue = Either; class GridBlockService { String gridId; - List fields; - LinkedHashMap blockMap = LinkedHashMap(); + GridBlockMap blockMap = GridBlockMap(); late GridBlockListener _blockListener; - PublishNotifier rowsUpdateNotifier = PublishNotifier(); + PublishNotifier blocksUpdateNotifier = PublishNotifier(); - GridBlockService({required this.gridId, required this.fields, required List blockOrders}) { - _loadGridBlocks(blockOrders: blockOrders); + GridBlockService({required this.gridId, required List blockOrders}) { + _loadGridBlocks(blockOrders); _blockListener = GridBlockListener(gridId: gridId); - _blockListener.rowsUpdateNotifier.addPublishListener((result) { + _blockListener.blockUpdateNotifier.addPublishListener((result) { result.fold( - (blockId) => _loadGridBlocks(blockOrders: [GridBlockOrder.create()..blockId = blockId.value]), + (blockOrder) => _loadGridBlocks(blockOrder), (err) => Log.error(err), ); }); _blockListener.start(); } - List buildRows() { - List rows = []; - blockMap.forEach((_, GridBlock gridBlock) { - rows.addAll(gridBlock.rowOrders.map( - (rowOrder) => GridRowData( - gridId: gridId, - fields: fields, - blockId: gridBlock.id, - rowId: rowOrder.rowId, - height: rowOrder.height.toDouble(), - ), - )); - }); - return rows; - } - Future stop() async { await _blockListener.stop(); } - void _loadGridBlocks({required List blockOrders}) { + void _loadGridBlocks(List blockOrders) { final payload = QueryGridBlocksPayload.create() ..gridId = gridId ..blockOrders.addAll(blockOrders); @@ -66,9 +49,9 @@ class GridBlockService { for (final gridBlock in repeatedBlocks.items) { blockMap[gridBlock.id] = gridBlock; } - rowsUpdateNotifier.value = left(buildRows()); + blocksUpdateNotifier.value = left(blockMap); }, - (err) => rowsUpdateNotifier.value = right(err), + (err) => blocksUpdateNotifier.value = right(err), ); }); } @@ -76,7 +59,7 @@ class GridBlockService { class GridBlockListener { final String gridId; - PublishNotifier> rowsUpdateNotifier = PublishNotifier(comparable: null); + PublishNotifier, FlowyError>> blockUpdateNotifier = PublishNotifier(comparable: null); StreamSubscription? _subscription; late GridNotificationParser _parser; @@ -95,10 +78,10 @@ class GridBlockListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.BlockDidUpdateRow: + case GridNotification.DidUpdateRow: result.fold( - (payload) => rowsUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), - (error) => rowsUpdateNotifier.value = right(error), + (payload) => blockUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]), + (error) => blockUpdateNotifier.value = right(error), ); break; @@ -109,6 +92,6 @@ class GridBlockListener { Future stop() async { await _subscription?.cancel(); - rowsUpdateNotifier.dispose(); + blockUpdateNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart index 55e29d915c..e0423d7757 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart @@ -1,4 +1,49 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; + +// typedef RowsUpdateNotifierValue = Either, FlowyError>; + class GridListener { - void start() {} - Future stop() async {} + final String gridId; + PublishNotifier, FlowyError>> fieldsUpdateNotifier = PublishNotifier(comparable: null); + StreamSubscription? _subscription; + late GridNotificationParser _parser; + GridListener({required this.gridId}); + + void start() { + _parser = GridNotificationParser( + id: gridId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.DidUpdateRow: + result.fold( + (payload) => fieldsUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), + (error) => fieldsUpdateNotifier.value = right(error), + ); + break; + default: + break; + } + } + + Future stop() async { + await _subscription?.cancel(); + fieldsUpdateNotifier.dispose(); + } } diff --git a/frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart b/frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart index 8bef2e41fd..e6b61af3e2 100644 --- a/frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart @@ -14,7 +14,7 @@ class TrashBloc extends Bloc { TrashBloc({required this.service, required this.listener}) : super(TrashState.init()) { on((event, emit) async { await event.map(initial: (e) async { - listener.startListening(trashUpdated: _listenTrashUpdated); + listener.start(trashUpdated: _listenTrashUpdated); final result = await service.readTrash(); emit(result.fold( (object) => state.copyWith(objects: object.items, successOrFailure: left(unit)), diff --git a/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart b/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart index 6a95de958e..dd0b1f58aa 100644 --- a/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart @@ -15,7 +15,7 @@ class TrashListener { TrashUpdatedCallback? _trashUpdated; late FolderNotificationParser _parser; - void startListening({TrashUpdatedCallback? trashUpdated}) { + void start({TrashUpdatedCallback? trashUpdated}) { _trashUpdated = trashUpdated; _parser = FolderNotificationParser(callback: _bservableCallback); _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); 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 1d6bc07891..1b79a7a0b4 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 @@ -83,17 +83,20 @@ class _FlowyGridState extends State { @override Widget build(BuildContext context) { + final gridId = context.read().view.id; + return BlocBuilder( buildWhen: (previous, current) => previous.fields != current.fields, builder: (context, state) { - return state.fields.fold( - () => const Center(child: CircularProgressIndicator.adaptive()), - (fields) => _wrapScrollbar(fields, [ - _buildHeader(fields), - _buildRows(context), - const GridFooter(), - ]), - ); + if (state.fields.isEmpty) { + return const Center(child: CircularProgressIndicator.adaptive()); + } + + return _wrapScrollbar(state.fields, [ + _buildHeader(gridId, state.fields), + _buildRows(context), + const GridFooter(), + ]); }, ); } @@ -108,19 +111,22 @@ class _FlowyGridState extends State { axis: Axis.horizontal, child: SizedBox( width: GridLayout.headerWidth(fields), - child: CustomScrollView( - physics: StyledScrollPhysics(), - controller: _scrollController.verticalController, - slivers: [...children], + child: ScrollConfiguration( + behavior: const ScrollBehavior().copyWith(scrollbars: false), + child: CustomScrollView( + physics: StyledScrollPhysics(), + controller: _scrollController.verticalController, + slivers: [...children], + ), ), ), ), ).padding(right: 0, top: GridSize.headerHeight, bottom: GridSize.scrollBarSize); } - Widget _buildHeader(List fields) { + Widget _buildHeader(String gridId, List fields) { return SliverPersistentHeader( - delegate: GridHeaderDelegate(fields), + delegate: GridHeaderDelegate(gridId: gridId, fields: fields), floating: true, pinned: true, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 40f6a3e3b0..f465e43843 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -12,13 +12,14 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'header_cell.dart'; class GridHeaderDelegate extends SliverPersistentHeaderDelegate { + final String gridId; final List fields; - GridHeaderDelegate(this.fields); + GridHeaderDelegate({required this.gridId, required this.fields}); @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return GridHeader(fields: fields); + return GridHeader(gridId: gridId, fields: fields); } @override @@ -38,36 +39,26 @@ class GridHeaderDelegate extends SliverPersistentHeaderDelegate { class GridHeader extends StatelessWidget { final List fields; - const GridHeader({required this.fields, Key? key}) : super(key: key); + final String gridId; + const GridHeader({required this.gridId, required this.fields, Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); return BlocProvider( - create: (context) => getIt(param1: fields)..add(const GridHeaderEvent.initial()), + create: (context) => getIt(param1: gridId, param2: fields)..add(const GridHeaderEvent.initial()), child: BlocBuilder( - builder: (context, state) { - final headers = state.fields - .map( - (field) => HeaderCellContainer( - width: field.width.toDouble(), - child: HeaderCell(field), - ), - ) - .toList(); - - return Container( - color: theme.surface, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _HeaderLeading(), - ...headers, - const _HeaderTrailing(), - ], - ), - ); - }, + builder: (context, state) => Container( + color: theme.surface, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _HeaderLeading(), + ...state.fields.map((field) => HeaderCell(field)), + const _HeaderTrailing(), + ], + ), + ), ), ); } @@ -97,13 +88,13 @@ class _HeaderTrailing extends StatelessWidget { border: Border(top: borderSide, bottom: borderSide), ), padding: GridSize.headerContentInsets, - child: const CreateColumnButton(), + child: const CreateFieldButton(), ); } } -class CreateColumnButton extends StatelessWidget { - const CreateColumnButton({Key? key}) : super(key: key); +class CreateFieldButton extends StatelessWidget { + const CreateFieldButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index fa8a3692c5..472c32d8f5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -17,34 +17,21 @@ class HeaderCell extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); - return FlowyButton( - text: Padding( - padding: GridSize.cellContentInsets, - child: FlowyText.medium(field.name, fontSize: 12), - ), + final button = FlowyButton( hoverColor: theme.hover, onTap: () => FieldEditor.show(context, field), rightIcon: svg("editor/details", color: theme.iconColor), + text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(field.name, fontSize: 12)), ); - } -} -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) { - final theme = context.watch(); final borderSide = BorderSide(color: theme.shader4, width: 0.4); + final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); + return Container( - width: width, - decoration: BoxDecoration( - border: Border(top: borderSide, right: borderSide, bottom: borderSide), - ), + width: field.width.toDouble(), + decoration: decoration, padding: GridSize.headerContentInsets, - child: child, + child: button, ); } } 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 c13b12e687..80b965177c 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 @@ -52,6 +52,40 @@ class GridEventGetFields { } } +class GridEventUpdateField { + FieldChangeset request; + GridEventUpdateField(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.UpdateField.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class GridEventCreateField { + CreateFieldPayload request; + GridEventCreateField(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.CreateField.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateRow { CreateRowPayload request; GridEventCreateRow(this.request); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index 5e5da6665d..d7119ad727 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -42,10 +42,12 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode UserIdInvalid = ErrorCode._(311, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid'); static const ErrorCode UserNotExist = ErrorCode._(312, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist'); static const ErrorCode TextTooLong = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextTooLong'); - static const ErrorCode BlockIdIsEmpty = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty'); - static const ErrorCode RowIdIsEmpty = ErrorCode._(402, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); - static const ErrorCode GridIdIsEmpty = ErrorCode._(403, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridIdIsEmpty'); - static const ErrorCode InvalidData = ErrorCode._(404, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); + static const ErrorCode GridIdIsEmpty = ErrorCode._(410, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridIdIsEmpty'); + static const ErrorCode BlockIdIsEmpty = ErrorCode._(420, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty'); + static const ErrorCode RowIdIsEmpty = ErrorCode._(430, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); + static const ErrorCode FieldIdIsEmpty = ErrorCode._(440, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldIdIsEmpty'); + static const ErrorCode TypeOptionIsEmpty = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionIsEmpty'); + static const ErrorCode InvalidData = ErrorCode._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); static const $core.List values = [ Internal, @@ -80,9 +82,11 @@ class ErrorCode extends $pb.ProtobufEnum { UserIdInvalid, UserNotExist, TextTooLong, + GridIdIsEmpty, BlockIdIsEmpty, RowIdIsEmpty, - GridIdIsEmpty, + FieldIdIsEmpty, + TypeOptionIsEmpty, InvalidData, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 7c18eb68e2..41815194f2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -44,12 +44,14 @@ const ErrorCode$json = const { const {'1': 'UserIdInvalid', '2': 311}, const {'1': 'UserNotExist', '2': 312}, const {'1': 'TextTooLong', '2': 400}, - const {'1': 'BlockIdIsEmpty', '2': 401}, - const {'1': 'RowIdIsEmpty', '2': 402}, - const {'1': 'GridIdIsEmpty', '2': 403}, - const {'1': 'InvalidData', '2': 404}, + const {'1': 'GridIdIsEmpty', '2': 410}, + const {'1': 'BlockIdIsEmpty', '2': 420}, + const {'1': 'RowIdIsEmpty', '2': 430}, + const {'1': 'FieldIdIsEmpty', '2': 440}, + const {'1': 'TypeOptionIsEmpty', '2': 441}, + const {'1': 'InvalidData', '2': 500}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxITCg5CbG9ja0lkSXNFbXB0eRCRAxIRCgxSb3dJZElzRW1wdHkQkgMSEgoNR3JpZElkSXNFbXB0eRCTAxIQCgtJbnZhbGlkRGF0YRCUAw=='); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFUeXBlT3B0aW9uSXNFbXB0eRC5AxIQCgtJbnZhbGlkRGF0YRD0Aw=='); 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 4462ce8b10..ce247ef7d6 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 @@ -979,6 +979,110 @@ class CreateRowPayload extends $pb.GeneratedMessage { void clearStartRowId() => clearField(2); } +enum CreateFieldPayload_OneOfStartFieldId { + startFieldId, + notSet +} + +class CreateFieldPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CreateFieldPayload_OneOfStartFieldId> _CreateFieldPayload_OneOfStartFieldIdByTag = { + 4 : CreateFieldPayload_OneOfStartFieldId.startFieldId, + 0 : CreateFieldPayload_OneOfStartFieldId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateFieldPayload', createEmptyInstance: create) + ..oo(0, [4]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY) + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startFieldId') + ..hasRequiredFields = false + ; + + CreateFieldPayload._() : super(); + factory CreateFieldPayload({ + $core.String? gridId, + Field? field_2, + $core.List<$core.int>? typeOptionData, + $core.String? startFieldId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (field_2 != null) { + _result.field_2 = field_2; + } + if (typeOptionData != null) { + _result.typeOptionData = typeOptionData; + } + if (startFieldId != null) { + _result.startFieldId = startFieldId; + } + return _result; + } + factory CreateFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateFieldPayload.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') + CreateFieldPayload clone() => CreateFieldPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateFieldPayload copyWith(void Function(CreateFieldPayload) updates) => super.copyWith((message) => updates(message as CreateFieldPayload)) as CreateFieldPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateFieldPayload create() => CreateFieldPayload._(); + CreateFieldPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateFieldPayload? _defaultInstance; + + CreateFieldPayload_OneOfStartFieldId whichOneOfStartFieldId() => _CreateFieldPayload_OneOfStartFieldIdByTag[$_whichOneof(0)]!; + void clearOneOfStartFieldId() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + Field get field_2 => $_getN(1); + @$pb.TagNumber(2) + set field_2(Field v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasField_2() => $_has(1); + @$pb.TagNumber(2) + void clearField_2() => clearField(2); + @$pb.TagNumber(2) + Field ensureField_2() => $_ensure(1); + + @$pb.TagNumber(3) + $core.List<$core.int> get typeOptionData => $_getN(2); + @$pb.TagNumber(3) + set typeOptionData($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasTypeOptionData() => $_has(2); + @$pb.TagNumber(3) + void clearTypeOptionData() => clearField(3); + + @$pb.TagNumber(4) + $core.String get startFieldId => $_getSZ(3); + @$pb.TagNumber(4) + set startFieldId($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasStartFieldId() => $_has(3); + @$pb.TagNumber(4) + void clearStartFieldId() => clearField(4); +} + class QueryFieldPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryFieldPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index cde3112874..adb25af959 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 @@ -207,6 +207,22 @@ const CreateRowPayload$json = const { /// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk'); +@$core.Deprecated('Use createFieldPayloadDescriptor instead') +const CreateFieldPayload$json = const { + '1': 'CreateFieldPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'field'}, + const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'}, + const {'1': 'start_field_id', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'startFieldId'}, + ], + '8': const [ + const {'1': 'one_of_start_field_id'}, + ], +}; + +/// Descriptor for `CreateFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createFieldPayloadDescriptor = $convert.base64Decode('ChJDcmVhdGVGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ='); @$core.Deprecated('Use queryFieldPayloadDescriptor instead') const QueryFieldPayload$json = const { '1': 'QueryFieldPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 4bbeae52a5..24f3409349 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -215,7 +215,7 @@ class FieldMeta extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') + ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOption') ..hasRequiredFields = false ; @@ -228,7 +228,7 @@ class FieldMeta extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - $core.String? typeOptions, + $core.String? typeOption, }) { final _result = create(); if (id != null) { @@ -252,8 +252,8 @@ class FieldMeta extends $pb.GeneratedMessage { if (width != null) { _result.width = width; } - if (typeOptions != null) { - _result.typeOptions = typeOptions; + if (typeOption != null) { + _result.typeOption = typeOption; } return _result; } @@ -342,13 +342,13 @@ class FieldMeta extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - $core.String get typeOptions => $_getSZ(7); + $core.String get typeOption => $_getSZ(7); @$pb.TagNumber(8) - set typeOptions($core.String v) { $_setString(7, v); } + set typeOption($core.String v) { $_setString(7, v); } @$pb.TagNumber(8) - $core.bool hasTypeOptions() => $_has(7); + $core.bool hasTypeOption() => $_has(7); @$pb.TagNumber(8) - void clearTypeOptions() => clearField(8); + void clearTypeOption() => clearField(8); } enum FieldChangeset_OneOfName { @@ -388,55 +388,57 @@ enum FieldChangeset_OneOfTypeOptions { class FieldChangeset extends $pb.GeneratedMessage { static const $core.Map<$core.int, FieldChangeset_OneOfName> _FieldChangeset_OneOfNameByTag = { - 2 : FieldChangeset_OneOfName.name, + 3 : FieldChangeset_OneOfName.name, 0 : FieldChangeset_OneOfName.notSet }; static const $core.Map<$core.int, FieldChangeset_OneOfDesc> _FieldChangeset_OneOfDescByTag = { - 3 : FieldChangeset_OneOfDesc.desc, + 4 : FieldChangeset_OneOfDesc.desc, 0 : FieldChangeset_OneOfDesc.notSet }; static const $core.Map<$core.int, FieldChangeset_OneOfFieldType> _FieldChangeset_OneOfFieldTypeByTag = { - 4 : FieldChangeset_OneOfFieldType.fieldType, + 5 : FieldChangeset_OneOfFieldType.fieldType, 0 : FieldChangeset_OneOfFieldType.notSet }; static const $core.Map<$core.int, FieldChangeset_OneOfFrozen> _FieldChangeset_OneOfFrozenByTag = { - 5 : FieldChangeset_OneOfFrozen.frozen, + 6 : FieldChangeset_OneOfFrozen.frozen, 0 : FieldChangeset_OneOfFrozen.notSet }; static const $core.Map<$core.int, FieldChangeset_OneOfVisibility> _FieldChangeset_OneOfVisibilityByTag = { - 6 : FieldChangeset_OneOfVisibility.visibility, + 7 : FieldChangeset_OneOfVisibility.visibility, 0 : FieldChangeset_OneOfVisibility.notSet }; static const $core.Map<$core.int, FieldChangeset_OneOfWidth> _FieldChangeset_OneOfWidthByTag = { - 7 : FieldChangeset_OneOfWidth.width, + 8 : FieldChangeset_OneOfWidth.width, 0 : FieldChangeset_OneOfWidth.notSet }; static const $core.Map<$core.int, FieldChangeset_OneOfTypeOptions> _FieldChangeset_OneOfTypeOptionsByTag = { - 8 : FieldChangeset_OneOfTypeOptions.typeOptions, + 9 : FieldChangeset_OneOfTypeOptions.typeOptions, 0 : FieldChangeset_OneOfTypeOptions.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangeset', createEmptyInstance: create) - ..oo(0, [2]) - ..oo(1, [3]) - ..oo(2, [4]) - ..oo(3, [5]) - ..oo(4, [6]) - ..oo(5, [7]) - ..oo(6, [8]) + ..oo(0, [3]) + ..oo(1, [4]) + ..oo(2, [5]) + ..oo(3, [6]) + ..oo(4, [7]) + ..oo(5, [8]) + ..oo(6, [9]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') - ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') - ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..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') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..aOS(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') ..hasRequiredFields = false ; FieldChangeset._() : super(); factory FieldChangeset({ $core.String? fieldId, + $core.String? gridId, $core.String? name, $core.String? desc, FieldType? fieldType, @@ -449,6 +451,9 @@ class FieldChangeset extends $pb.GeneratedMessage { if (fieldId != null) { _result.fieldId = fieldId; } + if (gridId != null) { + _result.gridId = gridId; + } if (name != null) { _result.name = name; } @@ -524,67 +529,76 @@ class FieldChangeset extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); + $core.String get gridId => $_getSZ(1); @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } + set gridId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); + $core.bool hasGridId() => $_has(1); @$pb.TagNumber(2) - void clearName() => clearField(2); + void clearGridId() => clearField(2); @$pb.TagNumber(3) - $core.String get desc => $_getSZ(2); + $core.String get name => $_getSZ(2); @$pb.TagNumber(3) - set desc($core.String v) { $_setString(2, v); } + set name($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasDesc() => $_has(2); + $core.bool hasName() => $_has(2); @$pb.TagNumber(3) - void clearDesc() => clearField(3); + void clearName() => clearField(3); @$pb.TagNumber(4) - FieldType get fieldType => $_getN(3); + $core.String get desc => $_getSZ(3); @$pb.TagNumber(4) - set fieldType(FieldType v) { setField(4, v); } + set desc($core.String v) { $_setString(3, v); } @$pb.TagNumber(4) - $core.bool hasFieldType() => $_has(3); + $core.bool hasDesc() => $_has(3); @$pb.TagNumber(4) - void clearFieldType() => clearField(4); + void clearDesc() => clearField(4); @$pb.TagNumber(5) - $core.bool get frozen => $_getBF(4); + FieldType get fieldType => $_getN(4); @$pb.TagNumber(5) - set frozen($core.bool v) { $_setBool(4, v); } + set fieldType(FieldType v) { setField(5, v); } @$pb.TagNumber(5) - $core.bool hasFrozen() => $_has(4); + $core.bool hasFieldType() => $_has(4); @$pb.TagNumber(5) - void clearFrozen() => clearField(5); + void clearFieldType() => clearField(5); @$pb.TagNumber(6) - $core.bool get visibility => $_getBF(5); + $core.bool get frozen => $_getBF(5); @$pb.TagNumber(6) - set visibility($core.bool v) { $_setBool(5, v); } + set frozen($core.bool v) { $_setBool(5, v); } @$pb.TagNumber(6) - $core.bool hasVisibility() => $_has(5); + $core.bool hasFrozen() => $_has(5); @$pb.TagNumber(6) - void clearVisibility() => clearField(6); + void clearFrozen() => clearField(6); @$pb.TagNumber(7) - $core.int get width => $_getIZ(6); + $core.bool get visibility => $_getBF(6); @$pb.TagNumber(7) - set width($core.int v) { $_setSignedInt32(6, v); } + set visibility($core.bool v) { $_setBool(6, v); } @$pb.TagNumber(7) - $core.bool hasWidth() => $_has(6); + $core.bool hasVisibility() => $_has(6); @$pb.TagNumber(7) - void clearWidth() => clearField(7); + void clearVisibility() => clearField(7); @$pb.TagNumber(8) - $core.String get typeOptions => $_getSZ(7); + $core.int get width => $_getIZ(7); @$pb.TagNumber(8) - set typeOptions($core.String v) { $_setString(7, v); } + set width($core.int v) { $_setSignedInt32(7, v); } @$pb.TagNumber(8) - $core.bool hasTypeOptions() => $_has(7); + $core.bool hasWidth() => $_has(7); @$pb.TagNumber(8) - void clearTypeOptions() => clearField(8); + void clearWidth() => clearField(8); + + @$pb.TagNumber(9) + $core.String get typeOptions => $_getSZ(8); + @$pb.TagNumber(9) + set typeOptions($core.String v) { $_setString(8, v); } + @$pb.TagNumber(9) + $core.bool hasTypeOptions() => $_has(8); + @$pb.TagNumber(9) + void clearTypeOptions() => clearField(9); } class AnyData extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index d20b9da3f5..cf69a051b1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -69,24 +69,25 @@ const FieldMeta$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '10': 'typeOptions'}, + const {'1': 'type_option', '3': 8, '4': 1, '5': 9, '10': 'typeOption'}, ], }; /// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSIQoMdHlwZV9vcHRpb25zGAggASgJUgt0eXBlT3B0aW9ucw=='); +final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSHwoLdHlwZV9vcHRpb24YCCABKAlSCnR5cGVPcHRpb24='); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', '2': const [ const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'name', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'name'}, - const {'1': 'desc', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'desc'}, - const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'}, - const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, - const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, - const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '9': 6, '10': 'typeOptions'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'}, + const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'}, + const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'}, + const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, + const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, + const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'}, + const {'1': 'type_options', '3': 9, '4': 1, '5': 9, '9': 6, '10': 'typeOptions'}, ], '8': const [ const {'1': 'one_of_name'}, @@ -100,7 +101,7 @@ const FieldChangeset$json = const { }; /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEiMKDHR5cGVfb3B0aW9ucxgIIAEoCUgGUgt0eXBlT3B0aW9uc0INCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIVChNvbmVfb2ZfdHlwZV9vcHRpb25z'); +final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSFAoEbmFtZRgDIAEoCUgAUgRuYW1lEhQKBGRlc2MYBCABKAlIAVIEZGVzYxIrCgpmaWVsZF90eXBlGAUgASgOMgouRmllbGRUeXBlSAJSCWZpZWxkVHlwZRIYCgZmcm96ZW4YBiABKAhIA1IGZnJvemVuEiAKCnZpc2liaWxpdHkYByABKAhIBFIKdmlzaWJpbGl0eRIWCgV3aWR0aBgIIAEoBUgFUgV3aWR0aBIjCgx0eXBlX29wdGlvbnMYCSABKAlIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart index 8481b81985..04b2ae6e81 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart @@ -9,14 +9,14 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -class CheckboxDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxDescription', createEmptyInstance: create) +class CheckboxTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxTypeOption', createEmptyInstance: create) ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') ..hasRequiredFields = false ; - CheckboxDescription._() : super(); - factory CheckboxDescription({ + CheckboxTypeOption._() : super(); + factory CheckboxTypeOption({ $core.bool? isSelected, }) { final _result = create(); @@ -25,26 +25,26 @@ class CheckboxDescription extends $pb.GeneratedMessage { } 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); + factory CheckboxTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CheckboxTypeOption.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); + CheckboxTypeOption clone() => CheckboxTypeOption()..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 + CheckboxTypeOption copyWith(void Function(CheckboxTypeOption) updates) => super.copyWith((message) => updates(message as CheckboxTypeOption)) as CheckboxTypeOption; // 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(); + static CheckboxTypeOption create() => CheckboxTypeOption._(); + CheckboxTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static CheckboxDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CheckboxDescription? _defaultInstance; + static CheckboxTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CheckboxTypeOption? _defaultInstance; @$pb.TagNumber(1) $core.bool get isSelected => $_getBF(0); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart index 6295b27033..0569b0665a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart @@ -8,13 +8,13 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use checkboxDescriptionDescriptor instead') -const CheckboxDescription$json = const { - '1': 'CheckboxDescription', +@$core.Deprecated('Use checkboxTypeOptionDescriptor instead') +const CheckboxTypeOption$json = const { + '1': 'CheckboxTypeOption', '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'); +/// Descriptor for `CheckboxTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List checkboxTypeOptionDescriptor = $convert.base64Decode('ChJDaGVja2JveFR5cGVPcHRpb24SHwoLaXNfc2VsZWN0ZWQYASABKAhSCmlzU2VsZWN0ZWQ='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pb.dart new file mode 100644 index 0000000000..fb907766cf --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pb.dart @@ -0,0 +1,58 @@ +/// +// Generated code. Do not modify. +// source: checkbox_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class CheckboxTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxTypeOption', createEmptyInstance: create) + ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') + ..hasRequiredFields = false + ; + + CheckboxTypeOption._() : super(); + factory CheckboxTypeOption({ + $core.bool? isSelected, + }) { + final _result = create(); + if (isSelected != null) { + _result.isSelected = isSelected; + } + return _result; + } + factory CheckboxTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CheckboxTypeOption.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') + CheckboxTypeOption clone() => CheckboxTypeOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CheckboxTypeOption copyWith(void Function(CheckboxTypeOption) updates) => super.copyWith((message) => updates(message as CheckboxTypeOption)) as CheckboxTypeOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CheckboxTypeOption create() => CheckboxTypeOption._(); + CheckboxTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CheckboxTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CheckboxTypeOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get isSelected => $_getBF(0); + @$pb.TagNumber(1) + set isSelected($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasIsSelected() => $_has(0); + @$pb.TagNumber(1) + void clearIsSelected() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbenum.dart new file mode 100644 index 0000000000..7c03d6985e --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: checkbox_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbjson.dart new file mode 100644 index 0000000000..33c4627985 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbjson.dart @@ -0,0 +1,20 @@ +/// +// Generated code. Do not modify. +// source: checkbox_type_option.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 checkboxTypeOptionDescriptor instead') +const CheckboxTypeOption$json = const { + '1': 'CheckboxTypeOption', + '2': const [ + const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, + ], +}; + +/// Descriptor for `CheckboxTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List checkboxTypeOptionDescriptor = $convert.base64Decode('ChJDaGVja2JveFR5cGVPcHRpb24SHwoLaXNfc2VsZWN0ZWQYASABKAhSCmlzU2VsZWN0ZWQ='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbserver.dart new file mode 100644 index 0000000000..5424623115 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_type_option.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: checkbox_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'checkbox_type_option.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 27985d016c..c000793a5e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -12,16 +12,16 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock'); - static const GridNotification BlockDidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockDidUpdateRow'); + static const GridNotification DidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); static const GridNotification GridDidUpdateCells = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); - static const GridNotification GridDidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); + static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields'); static const $core.List values = [ Unknown, GridDidCreateBlock, - BlockDidUpdateRow, + DidUpdateRow, GridDidUpdateCells, - GridDidUpdateFields, + DidUpdateFields, ]; static final $core.Map<$core.int, GridNotification> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 0eebf85cc6..5dc1fbc1a5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -14,11 +14,11 @@ const GridNotification$json = const { '2': const [ const {'1': 'Unknown', '2': 0}, const {'1': 'GridDidCreateBlock', '2': 11}, - const {'1': 'BlockDidUpdateRow', '2': 20}, + const {'1': 'DidUpdateRow', '2': 20}, const {'1': 'GridDidUpdateCells', '2': 30}, - const {'1': 'GridDidUpdateFields', '2': 40}, + const {'1': 'DidUpdateFields', '2': 40}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIVChFCbG9ja0RpZFVwZGF0ZVJvdxAUEhYKEkdyaWREaWRVcGRhdGVDZWxscxAeEhcKE0dyaWREaWRVcGRhdGVGaWVsZHMQKA=='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIQCgxEaWRVcGRhdGVSb3cQFBIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQHhITCg9EaWRVcGRhdGVGaWVsZHMQKA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart new file mode 100644 index 0000000000..85c5e55111 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart @@ -0,0 +1,76 @@ +/// +// Generated code. Do not modify. +// source: date_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'date_type_option.pbenum.dart'; + +export 'date_type_option.pbenum.dart'; + +class DateTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateTypeOption', 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 + ; + + DateTypeOption._() : super(); + factory DateTypeOption({ + DateFormat? dateFormat, + TimeFormat? timeFormat, + }) { + final _result = create(); + if (dateFormat != null) { + _result.dateFormat = dateFormat; + } + if (timeFormat != null) { + _result.timeFormat = timeFormat; + } + return _result; + } + factory DateTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DateTypeOption.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') + DateTypeOption clone() => DateTypeOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DateTypeOption copyWith(void Function(DateTypeOption) updates) => super.copyWith((message) => updates(message as DateTypeOption)) as DateTypeOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static DateTypeOption create() => DateTypeOption._(); + DateTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DateTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DateTypeOption? _defaultInstance; + + @$pb.TagNumber(1) + DateFormat get dateFormat => $_getN(0); + @$pb.TagNumber(1) + set dateFormat(DateFormat v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasDateFormat() => $_has(0); + @$pb.TagNumber(1) + void clearDateFormat() => clearField(1); + + @$pb.TagNumber(2) + TimeFormat get timeFormat => $_getN(1); + @$pb.TagNumber(2) + set timeFormat(TimeFormat v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTimeFormat() => $_has(1); + @$pb.TagNumber(2) + void clearTimeFormat() => clearField(2); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbenum.dart new file mode 100644 index 0000000000..63255cb1ab --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbenum.dart @@ -0,0 +1,45 @@ +/// +// Generated code. Do not modify. +// source: date_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class DateFormat extends $pb.ProtobufEnum { + static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); + static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); + static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); + static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); + + static const $core.List values = [ + Local, + US, + ISO, + Friendly, + ]; + + static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static DateFormat? valueOf($core.int value) => _byValue[value]; + + const DateFormat._($core.int v, $core.String n) : super(v, n); +} + +class TimeFormat extends $pb.ProtobufEnum { + static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); + static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); + + static const $core.List values = [ + TwelveHour, + TwentyFourHour, + ]; + + static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static TimeFormat? valueOf($core.int value) => _byValue[value]; + + const TimeFormat._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart new file mode 100644 index 0000000000..9acf67241b --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart @@ -0,0 +1,45 @@ +/// +// Generated code. Do not modify. +// source: date_type_option.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 dateTypeOptionDescriptor instead') +const DateTypeOption$json = const { + '1': 'DateTypeOption', + '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 `DateTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List dateTypeOptionDescriptor = $convert.base64Decode('Cg5EYXRlVHlwZU9wdGlvbhIsCgtkYXRlX2Zvcm1hdBgBIAEoDjILLkRhdGVGb3JtYXRSCmRhdGVGb3JtYXQSLAoLdGltZV9mb3JtYXQYAiABKA4yCy5UaW1lRm9ybWF0Ugp0aW1lRm9ybWF0'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbserver.dart new file mode 100644 index 0000000000..b95719d206 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: date_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'date_type_option.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 91a3861076..4488ba1a3d 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 @@ -13,14 +13,18 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetGridData = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridData'); static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks'); static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); - static const GridEvent CreateRow = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); - static const GridEvent GetRow = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); - static const GridEvent UpdateCell = GridEvent._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); + static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); + static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); + static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, GetGridBlocks, GetFields, + UpdateField, + CreateField, CreateRow, GetRow, UpdateCell, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index c203b10c75..c70007eaaa 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 @@ -15,11 +15,13 @@ const GridEvent$json = const { const {'1': 'GetGridData', '2': 0}, const {'1': 'GetGridBlocks', '2': 1}, const {'1': 'GetFields', '2': 10}, - const {'1': 'CreateRow', '2': 11}, - const {'1': 'GetRow', '2': 12}, - const {'1': 'UpdateCell', '2': 20}, + const {'1': 'UpdateField', '2': 11}, + const {'1': 'CreateField', '2': 12}, + const {'1': 'CreateRow', '2': 21}, + const {'1': 'GetRow', '2': 22}, + const {'1': 'UpdateCell', '2': 30}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDQoJQ3JlYXRlUm93EAsSCgoGR2V0Um93EAwSDgoKVXBkYXRlQ2VsbBAU'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg0KCUNyZWF0ZVJvdxAVEgoKBkdldFJvdxAWEg4KClVwZGF0ZUNlbGwQHg=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart new file mode 100644 index 0000000000..54f4d9546f --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart @@ -0,0 +1,118 @@ +/// +// Generated code. Do not modify. +// source: number_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'number_type_option.pbenum.dart'; + +export 'number_type_option.pbenum.dart'; + +class NumberTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberTypeOption', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format', $pb.PbFieldType.OE, defaultOrMaker: NumberFormat.Number, valueOf: NumberFormat.valueOf, enumValues: NumberFormat.values) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..hasRequiredFields = false + ; + + NumberTypeOption._() : super(); + factory NumberTypeOption({ + NumberFormat? format, + $core.int? scale, + $core.String? symbol, + $core.bool? signPositive, + $core.String? name, + }) { + final _result = create(); + if (format != null) { + _result.format = format; + } + 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 NumberTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NumberTypeOption.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') + NumberTypeOption clone() => NumberTypeOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NumberTypeOption copyWith(void Function(NumberTypeOption) updates) => super.copyWith((message) => updates(message as NumberTypeOption)) as NumberTypeOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NumberTypeOption create() => NumberTypeOption._(); + NumberTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NumberTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NumberTypeOption? _defaultInstance; + + @$pb.TagNumber(1) + NumberFormat get format => $_getN(0); + @$pb.TagNumber(1) + set format(NumberFormat v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasFormat() => $_has(0); + @$pb.TagNumber(1) + void clearFormat() => clearField(1); + + @$pb.TagNumber(2) + $core.int get scale => $_getIZ(1); + @$pb.TagNumber(2) + set scale($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasScale() => $_has(1); + @$pb.TagNumber(2) + void clearScale() => clearField(2); + + @$pb.TagNumber(3) + $core.String get symbol => $_getSZ(2); + @$pb.TagNumber(3) + set symbol($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasSymbol() => $_has(2); + @$pb.TagNumber(3) + void clearSymbol() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get signPositive => $_getBF(3); + @$pb.TagNumber(4) + set signPositive($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasSignPositive() => $_has(3); + @$pb.TagNumber(4) + void clearSignPositive() => clearField(4); + + @$pb.TagNumber(5) + $core.String get name => $_getSZ(4); + @$pb.TagNumber(5) + set name($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasName() => $_has(4); + @$pb.TagNumber(5) + void clearName() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart new file mode 100644 index 0000000000..5e486443c6 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart @@ -0,0 +1,30 @@ +/// +// Generated code. Do not modify. +// source: number_type_option.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 NumberFormat extends $pb.ProtobufEnum { + static const NumberFormat Number = NumberFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const NumberFormat USD = NumberFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + static const NumberFormat CNY = NumberFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const NumberFormat EUR = NumberFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + + static const $core.List values = [ + Number, + USD, + CNY, + EUR, + ]; + + static final $core.Map<$core.int, NumberFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static NumberFormat? valueOf($core.int value) => _byValue[value]; + + const NumberFormat._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart new file mode 100644 index 0000000000..d3c593d40e --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart @@ -0,0 +1,37 @@ +/// +// Generated code. Do not modify. +// source: number_type_option.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 numberFormatDescriptor instead') +const NumberFormat$json = const { + '1': 'NumberFormat', + '2': const [ + const {'1': 'Number', '2': 0}, + const {'1': 'USD', '2': 1}, + const {'1': 'CNY', '2': 2}, + const {'1': 'EUR', '2': 3}, + ], +}; + +/// Descriptor for `NumberFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List numberFormatDescriptor = $convert.base64Decode('CgxOdW1iZXJGb3JtYXQSCgoGTnVtYmVyEAASBwoDVVNEEAESBwoDQ05ZEAISBwoDRVVSEAM='); +@$core.Deprecated('Use numberTypeOptionDescriptor instead') +const NumberTypeOption$json = const { + '1': 'NumberTypeOption', + '2': const [ + const {'1': 'format', '3': 1, '4': 1, '5': 14, '6': '.NumberFormat', '10': 'format'}, + const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, + const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, + const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, + const {'1': 'name', '3': 5, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `NumberTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List numberTypeOptionDescriptor = $convert.base64Decode('ChBOdW1iZXJUeXBlT3B0aW9uEiUKBmZvcm1hdBgBIAEoDjINLk51bWJlckZvcm1hdFIGZm9ybWF0EhQKBXNjYWxlGAIgASgNUgVzY2FsZRIWCgZzeW1ib2wYAyABKAlSBnN5bWJvbBIjCg1zaWduX3Bvc2l0aXZlGAQgASgIUgxzaWduUG9zaXRpdmUSEgoEbmFtZRgFIAEoCVIEbmFtZQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbserver.dart new file mode 100644 index 0000000000..107c3a1d86 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: number_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'number_type_option.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index daefe6a170..8f0a7e7d48 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,8 +1,8 @@ // Auto-generated, do not edit -export './date_description.pb.dart'; +export './number_type_option.pb.dart'; export './text_description.pb.dart'; export './dart_notification.pb.dart'; -export './checkbox_description.pb.dart'; -export './selection_description.pb.dart'; +export './selection_type_option.pb.dart'; +export './checkbox_type_option.pb.dart'; export './event_map.pb.dart'; -export './number_description.pb.dart'; +export './date_type_option.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart new file mode 100644 index 0000000000..f2222d82b8 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -0,0 +1,196 @@ +/// +// Generated code. Do not modify. +// source: selection_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class SingleSelectTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectTypeOption', 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 + ; + + SingleSelectTypeOption._() : super(); + factory SingleSelectTypeOption({ + $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 SingleSelectTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SingleSelectTypeOption.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') + SingleSelectTypeOption clone() => SingleSelectTypeOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SingleSelectTypeOption copyWith(void Function(SingleSelectTypeOption) updates) => super.copyWith((message) => updates(message as SingleSelectTypeOption)) as SingleSelectTypeOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SingleSelectTypeOption create() => SingleSelectTypeOption._(); + SingleSelectTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SingleSelectTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SingleSelectTypeOption? _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 MultiSelectTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectTypeOption', 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 + ; + + MultiSelectTypeOption._() : super(); + factory MultiSelectTypeOption({ + $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 MultiSelectTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MultiSelectTypeOption.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') + MultiSelectTypeOption clone() => MultiSelectTypeOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MultiSelectTypeOption copyWith(void Function(MultiSelectTypeOption) updates) => super.copyWith((message) => updates(message as MultiSelectTypeOption)) as MultiSelectTypeOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MultiSelectTypeOption create() => MultiSelectTypeOption._(); + MultiSelectTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MultiSelectTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MultiSelectTypeOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class SelectOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') + ..hasRequiredFields = false + ; + + SelectOption._() : super(); + factory SelectOption({ + $core.String? id, + $core.String? name, + $core.String? color, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (color != null) { + _result.color = color; + } + return _result; + } + factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SelectOption clone() => SelectOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOption create() => SelectOption._(); + SelectOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get color => $_getSZ(2); + @$pb.TagNumber(3) + set color($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasColor() => $_has(2); + @$pb.TagNumber(3) + void clearColor() => clearField(3); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart new file mode 100644 index 0000000000..9a52c17f7d --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: selection_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart new file mode 100644 index 0000000000..fdfc6833b0 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -0,0 +1,44 @@ +/// +// Generated code. Do not modify. +// source: selection_type_option.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 singleSelectTypeOptionDescriptor instead') +const SingleSelectTypeOption$json = const { + '1': 'SingleSelectTypeOption', + '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 `SingleSelectTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List singleSelectTypeOptionDescriptor = $convert.base64Decode('ChZTaW5nbGVTZWxlY3RUeXBlT3B0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); +@$core.Deprecated('Use multiSelectTypeOptionDescriptor instead') +const MultiSelectTypeOption$json = const { + '1': 'MultiSelectTypeOption', + '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 `MultiSelectTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List multiSelectTypeOptionDescriptor = $convert.base64Decode('ChVNdWx0aVNlbGVjdFR5cGVPcHRpb24SJwoHb3B0aW9ucxgBIAMoCzINLlNlbGVjdE9wdGlvblIHb3B0aW9ucxIjCg1kaXNhYmxlX2NvbG9yGAIgASgIUgxkaXNhYmxlQ29sb3I='); +@$core.Deprecated('Use selectOptionDescriptor instead') +const SelectOption$json = const { + '1': 'SelectOption', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, + ], +}; + +/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbserver.dart new file mode 100644 index 0000000000..2e9ff7c00b --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: selection_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'selection_type_option.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart index 9434b2fc90..c8f930be1b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart @@ -9,14 +9,14 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -class RichTextDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextDescription', createEmptyInstance: create) +class RichTextTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextTypeOption', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') ..hasRequiredFields = false ; - RichTextDescription._() : super(); - factory RichTextDescription({ + RichTextTypeOption._() : super(); + factory RichTextTypeOption({ $core.String? format, }) { final _result = create(); @@ -25,26 +25,26 @@ class RichTextDescription extends $pb.GeneratedMessage { } 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); + factory RichTextTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RichTextTypeOption.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); + RichTextTypeOption clone() => RichTextTypeOption()..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 + RichTextTypeOption copyWith(void Function(RichTextTypeOption) updates) => super.copyWith((message) => updates(message as RichTextTypeOption)) as RichTextTypeOption; // 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(); + static RichTextTypeOption create() => RichTextTypeOption._(); + RichTextTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static RichTextDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RichTextDescription? _defaultInstance; + static RichTextTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RichTextTypeOption? _defaultInstance; @$pb.TagNumber(1) $core.String get format => $_getSZ(0); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart index fdf2098d47..ebe805501b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart @@ -8,13 +8,13 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use richTextDescriptionDescriptor instead') -const RichTextDescription$json = const { - '1': 'RichTextDescription', +@$core.Deprecated('Use richTextTypeOptionDescriptor instead') +const RichTextTypeOption$json = const { + '1': 'RichTextTypeOption', '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'); +/// Descriptor for `RichTextTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List richTextTypeOptionDescriptor = $convert.base64Decode('ChJSaWNoVGV4dFR5cGVPcHRpb24SFgoGZm9ybWF0GAEgASgJUgZmb3JtYXQ='); diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index b310e3fcd7..d0b6c8dec5 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/cell/description", "src/dart_notification.rs"] +proto_crates = ["src/event_map.rs", "src/services/field/type_options", "src/dart_notification.rs"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 927b71d957..34c972a9bb 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -8,10 +8,10 @@ pub enum GridNotification { GridDidCreateBlock = 11, - BlockDidUpdateRow = 20, + DidUpdateRow = 20, GridDidUpdateCells = 30, - GridDidUpdateFields = 40, + DidUpdateFields = 40, } impl std::default::Default for GridNotification { diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 73aed6da43..59e3aa2a39 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,10 +1,12 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, - QueryRowPayload, RepeatedField, RepeatedGridBlock, Row, + CellMetaChangeset, CreateFieldPayload, CreateRowPayload, Field, FieldChangeset, Grid, GridId, QueryFieldPayload, + QueryGridBlocksPayload, QueryRowPayload, RepeatedField, RepeatedGridBlock, Row, +}; +use flowy_grid_data_model::parser::{ + CreateFieldParams, CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams, }; -use flowy_grid_data_model::parser::{CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -35,6 +37,40 @@ pub(crate) async fn get_grid_blocks_handler( data_result(repeated_grid_block) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn get_fields_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: QueryFieldParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let field_metas = editor.get_field_metas(Some(params.field_orders)).await?; + let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); + data_result(repeated_field) +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn update_field_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let changeset: FieldChangeset = data.into_inner(); + let editor = manager.get_grid_editor(&changeset.grid_id)?; + let _ = editor.update_field(changeset).await?; + Ok(()) +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn create_field_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let params: CreateFieldParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.create_field(params).await?; + Ok(()) +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_row_handler( data: Data, @@ -48,18 +84,6 @@ pub(crate) async fn get_row_handler( } } -#[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn get_fields_handler( - data: Data, - manager: AppData>, -) -> DataResult { - let params: QueryFieldParams = data.into_inner().try_into()?; - let editor = manager.get_grid_editor(¶ms.grid_id)?; - let field_metas = editor.get_field_metas(Some(params.field_orders)).await?; - let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); - data_result(repeated_field) -} - #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_row_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 03b27f4c70..944c58d13b 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -11,6 +11,8 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetFields, get_fields_handler) + .event(GridEvent::UpdateField, update_field_handler) + .event(GridEvent::CreateField, create_field_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); @@ -30,12 +32,18 @@ pub enum GridEvent { #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 10, + #[event(input = "FieldChangeset")] + UpdateField = 11, + + #[event(input = "CreateFieldPayload")] + CreateField = 12, + #[event(input = "CreateRowPayload", output = "Row")] - CreateRow = 11, + CreateRow = 21, #[event(input = "QueryRowPayload", output = "Row")] - GetRow = 12, + GetRow = 22, #[event(input = "CellMetaChangeset")] - UpdateCell = 20, + UpdateCell = 30, } diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index d7a5fc8bf8..b4a9cf1531 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -11,7 +11,7 @@ macro_rules! impl_from_field_type_option { ($target: ident) => { impl std::convert::From<&FieldMeta> for $target { fn from(field_meta: &FieldMeta) -> $target { - match serde_json::from_str(&field_meta.type_options) { + match serde_json::from_str(&field_meta.type_option) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_type_option.rs similarity index 82% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_type_option.rs index 276617efbd..95612e4765 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_type_option.rs @@ -17,14 +17,14 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `checkbox_description.proto` +//! Generated file from `checkbox_type_option.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct CheckboxDescription { +pub struct CheckboxTypeOption { // message fields pub is_selected: bool, // special fields @@ -32,14 +32,14 @@ pub struct CheckboxDescription { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a CheckboxDescription { - fn default() -> &'a CheckboxDescription { - ::default_instance() +impl<'a> ::std::default::Default for &'a CheckboxTypeOption { + fn default() -> &'a CheckboxTypeOption { + ::default_instance() } } -impl CheckboxDescription { - pub fn new() -> CheckboxDescription { +impl CheckboxTypeOption { + pub fn new() -> CheckboxTypeOption { ::std::default::Default::default() } @@ -59,7 +59,7 @@ impl CheckboxDescription { } } -impl ::protobuf::Message for CheckboxDescription { +impl ::protobuf::Message for CheckboxTypeOption { fn is_initialized(&self) -> bool { true } @@ -129,8 +129,8 @@ impl ::protobuf::Message for CheckboxDescription { Self::descriptor_static() } - fn new() -> CheckboxDescription { - CheckboxDescription::new() + fn new() -> CheckboxTypeOption { + CheckboxTypeOption::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -139,44 +139,44 @@ impl ::protobuf::Message for CheckboxDescription { 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 }, + |m: &CheckboxTypeOption| { &m.is_selected }, + |m: &mut CheckboxTypeOption| { &mut m.is_selected }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CheckboxDescription", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CheckboxTypeOption", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static CheckboxDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CheckboxDescription::new) + fn default_instance() -> &'static CheckboxTypeOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CheckboxTypeOption::new) } } -impl ::protobuf::Clear for CheckboxDescription { +impl ::protobuf::Clear for CheckboxTypeOption { fn clear(&mut self) { self.is_selected = false; self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for CheckboxDescription { +impl ::std::fmt::Debug for CheckboxTypeOption { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CheckboxDescription { +impl ::protobuf::reflect::ProtobufValue for CheckboxTypeOption { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x1acheckbox_description.proto\"6\n\x13CheckboxDescription\x12\x1f\n\ + \n\x1acheckbox_type_option.proto\"5\n\x12CheckboxTypeOption\x12\x1f\n\ \x0bis_selected\x18\x01\x20\x01(\x08R\nisSelectedb\x06proto3\ "; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 4562b238c0..0dd067b3d5 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -27,9 +27,9 @@ pub enum GridNotification { Unknown = 0, GridDidCreateBlock = 11, - BlockDidUpdateRow = 20, + DidUpdateRow = 20, GridDidUpdateCells = 30, - GridDidUpdateFields = 40, + DidUpdateFields = 40, } impl ::protobuf::ProtobufEnum for GridNotification { @@ -41,9 +41,9 @@ impl ::protobuf::ProtobufEnum for GridNotification { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), 11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock), - 20 => ::std::option::Option::Some(GridNotification::BlockDidUpdateRow), + 20 => ::std::option::Option::Some(GridNotification::DidUpdateRow), 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), - 40 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), + 40 => ::std::option::Option::Some(GridNotification::DidUpdateFields), _ => ::std::option::Option::None } } @@ -52,9 +52,9 @@ impl ::protobuf::ProtobufEnum for GridNotification { static values: &'static [GridNotification] = &[ GridNotification::Unknown, GridNotification::GridDidCreateBlock, - GridNotification::BlockDidUpdateRow, + GridNotification::DidUpdateRow, GridNotification::GridDidUpdateCells, - GridNotification::GridDidUpdateFields, + GridNotification::DidUpdateFields, ]; values } @@ -83,10 +83,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x7f\n\x10GridNotification\x12\x0b\n\x07Un\ - known\x10\0\x12\x16\n\x12GridDidCreateBlock\x10\x0b\x12\x15\n\x11BlockDi\ - dUpdateRow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x17\n\x13\ - GridDidUpdateFields\x10(b\x06proto3\ + \n\x17dart_notification.proto*v\n\x10GridNotification\x12\x0b\n\x07Unkno\ + wn\x10\0\x12\x16\n\x12GridDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUpdateR\ + ow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDidUpdat\ + eFields\x10(b\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/date_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs similarity index 87% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs index 05b2bc6a0f..5287fa32d6 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs @@ -17,14 +17,14 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `date_description.proto` +//! Generated file from `date_type_option.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct DateDescription { +pub struct DateTypeOption { // message fields pub date_format: DateFormat, pub time_format: TimeFormat, @@ -33,14 +33,14 @@ pub struct DateDescription { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a DateDescription { - fn default() -> &'a DateDescription { - ::default_instance() +impl<'a> ::std::default::Default for &'a DateTypeOption { + fn default() -> &'a DateTypeOption { + ::default_instance() } } -impl DateDescription { - pub fn new() -> DateDescription { +impl DateTypeOption { + pub fn new() -> DateTypeOption { ::std::default::Default::default() } @@ -75,7 +75,7 @@ impl DateDescription { } } -impl ::protobuf::Message for DateDescription { +impl ::protobuf::Message for DateTypeOption { fn is_initialized(&self) -> bool { true } @@ -150,8 +150,8 @@ impl ::protobuf::Message for DateDescription { Self::descriptor_static() } - fn new() -> DateDescription { - DateDescription::new() + fn new() -> DateTypeOption { + DateTypeOption::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -160,29 +160,29 @@ impl ::protobuf::Message for DateDescription { 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 }, + |m: &DateTypeOption| { &m.date_format }, + |m: &mut DateTypeOption| { &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 }, + |m: &DateTypeOption| { &m.time_format }, + |m: &mut DateTypeOption| { &mut m.time_format }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "DateDescription", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "DateTypeOption", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static DateDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(DateDescription::new) + fn default_instance() -> &'static DateTypeOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(DateTypeOption::new) } } -impl ::protobuf::Clear for DateDescription { +impl ::protobuf::Clear for DateTypeOption { fn clear(&mut self) { self.date_format = DateFormat::Local; self.time_format = TimeFormat::TwelveHour; @@ -190,13 +190,13 @@ impl ::protobuf::Clear for DateDescription { } } -impl ::std::fmt::Debug for DateDescription { +impl ::std::fmt::Debug for DateTypeOption { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for DateDescription { +impl ::protobuf::reflect::ProtobufValue for DateTypeOption { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -309,9 +309,9 @@ impl ::protobuf::reflect::ProtobufValue for TimeFormat { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x16date_description.proto\"m\n\x0fDateDescription\x12,\n\x0bdate_form\ - at\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btime_form\ - at\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat*6\n\nDateFormat\x12\ + \n\x16date_type_option.proto\"l\n\x0eDateTypeOption\x12,\n\x0bdate_forma\ + t\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btime_forma\ + t\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat*6\n\nDateFormat\x12\ \t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\ \x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\ \x12\x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\ 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 9feb87fec5..0ba8fdebc4 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 @@ -28,9 +28,11 @@ pub enum GridEvent { GetGridData = 0, GetGridBlocks = 1, GetFields = 10, - CreateRow = 11, - GetRow = 12, - UpdateCell = 20, + UpdateField = 11, + CreateField = 12, + CreateRow = 21, + GetRow = 22, + UpdateCell = 30, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -43,9 +45,11 @@ impl ::protobuf::ProtobufEnum for GridEvent { 0 => ::std::option::Option::Some(GridEvent::GetGridData), 1 => ::std::option::Option::Some(GridEvent::GetGridBlocks), 10 => ::std::option::Option::Some(GridEvent::GetFields), - 11 => ::std::option::Option::Some(GridEvent::CreateRow), - 12 => ::std::option::Option::Some(GridEvent::GetRow), - 20 => ::std::option::Option::Some(GridEvent::UpdateCell), + 11 => ::std::option::Option::Some(GridEvent::UpdateField), + 12 => ::std::option::Option::Some(GridEvent::CreateField), + 21 => ::std::option::Option::Some(GridEvent::CreateRow), + 22 => ::std::option::Option::Some(GridEvent::GetRow), + 30 => ::std::option::Option::Some(GridEvent::UpdateCell), _ => ::std::option::Option::None } } @@ -55,6 +59,8 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetGridData, GridEvent::GetGridBlocks, GridEvent::GetFields, + GridEvent::UpdateField, + GridEvent::CreateField, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, @@ -86,10 +92,11 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*i\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ - \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\r\n\tCreateRo\ - w\x10\x0b\x12\n\n\x06GetRow\x10\x0c\x12\x0e\n\nUpdateCell\x10\x14b\x06pr\ - oto3\ + \n\x0fevent_map.proto*\x8b\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ + \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\r\n\tCreate\ + Row\x10\x15\x12\n\n\x06GetRow\x10\x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06\ + proto3\ "; 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 a616a281d6..2e768a115b 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,8 +1,8 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit -mod date_description; -pub use date_description::*; +mod number_type_option; +pub use number_type_option::*; mod text_description; pub use text_description::*; @@ -10,14 +10,14 @@ pub use text_description::*; mod dart_notification; pub use dart_notification::*; -mod checkbox_description; -pub use checkbox_description::*; +mod selection_type_option; +pub use selection_type_option::*; -mod selection_description; -pub use selection_description::*; +mod checkbox_type_option; +pub use checkbox_type_option::*; mod event_map; pub use event_map::*; -mod number_description; -pub use number_description::*; +mod date_type_option; +pub use date_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs similarity index 88% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs index 2137ea2be1..8fd65bc20b 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs @@ -17,14 +17,14 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `number_description.proto` +//! Generated file from `number_type_option.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct NumberDescription { +pub struct NumberTypeOption { // message fields pub format: NumberFormat, pub scale: u32, @@ -36,14 +36,14 @@ pub struct NumberDescription { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a NumberDescription { - fn default() -> &'a NumberDescription { - ::default_instance() +impl<'a> ::std::default::Default for &'a NumberTypeOption { + fn default() -> &'a NumberTypeOption { + ::default_instance() } } -impl NumberDescription { - pub fn new() -> NumberDescription { +impl NumberTypeOption { + pub fn new() -> NumberTypeOption { ::std::default::Default::default() } @@ -145,7 +145,7 @@ impl NumberDescription { } } -impl ::protobuf::Message for NumberDescription { +impl ::protobuf::Message for NumberTypeOption { fn is_initialized(&self) -> bool { true } @@ -255,8 +255,8 @@ impl ::protobuf::Message for NumberDescription { Self::descriptor_static() } - fn new() -> NumberDescription { - NumberDescription::new() + fn new() -> NumberTypeOption { + NumberTypeOption::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -265,44 +265,44 @@ impl ::protobuf::Message for NumberDescription { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "format", - |m: &NumberDescription| { &m.format }, - |m: &mut NumberDescription| { &mut m.format }, + |m: &NumberTypeOption| { &m.format }, + |m: &mut NumberTypeOption| { &mut m.format }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( "scale", - |m: &NumberDescription| { &m.scale }, - |m: &mut NumberDescription| { &mut m.scale }, + |m: &NumberTypeOption| { &m.scale }, + |m: &mut NumberTypeOption| { &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 }, + |m: &NumberTypeOption| { &m.symbol }, + |m: &mut NumberTypeOption| { &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 }, + |m: &NumberTypeOption| { &m.sign_positive }, + |m: &mut NumberTypeOption| { &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 }, + |m: &NumberTypeOption| { &m.name }, + |m: &mut NumberTypeOption| { &mut m.name }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "NumberDescription", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "NumberTypeOption", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static NumberDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(NumberDescription::new) + fn default_instance() -> &'static NumberTypeOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(NumberTypeOption::new) } } -impl ::protobuf::Clear for NumberDescription { +impl ::protobuf::Clear for NumberTypeOption { fn clear(&mut self) { self.format = NumberFormat::Number; self.scale = 0; @@ -313,13 +313,13 @@ impl ::protobuf::Clear for NumberDescription { } } -impl ::std::fmt::Debug for NumberDescription { +impl ::std::fmt::Debug for NumberTypeOption { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for NumberDescription { +impl ::protobuf::reflect::ProtobufValue for NumberTypeOption { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -382,7 +382,7 @@ impl ::protobuf::reflect::ProtobufValue for NumberFormat { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x18number_description.proto\"\xa1\x01\n\x11NumberDescription\x12%\n\ + \n\x18number_type_option.proto\"\xa0\x01\n\x10NumberTypeOption\x12%\n\ \x06format\x18\x01\x20\x01(\x0e2\r.NumberFormatR\x06format\x12\x14\n\x05\ scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\ \tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositiv\ diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs similarity index 87% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index 9feda09402..6d12dbc81f 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -17,14 +17,14 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `selection_description.proto` +//! Generated file from `selection_type_option.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct SingleSelectDescription { +pub struct SingleSelectTypeOption { // message fields pub options: ::protobuf::RepeatedField, pub disable_color: bool, @@ -33,14 +33,14 @@ pub struct SingleSelectDescription { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a SingleSelectDescription { - fn default() -> &'a SingleSelectDescription { - ::default_instance() +impl<'a> ::std::default::Default for &'a SingleSelectTypeOption { + fn default() -> &'a SingleSelectTypeOption { + ::default_instance() } } -impl SingleSelectDescription { - pub fn new() -> SingleSelectDescription { +impl SingleSelectTypeOption { + pub fn new() -> SingleSelectTypeOption { ::std::default::Default::default() } @@ -85,7 +85,7 @@ impl SingleSelectDescription { } } -impl ::protobuf::Message for SingleSelectDescription { +impl ::protobuf::Message for SingleSelectTypeOption { fn is_initialized(&self) -> bool { for v in &self.options { if !v.is_initialized() { @@ -172,8 +172,8 @@ impl ::protobuf::Message for SingleSelectDescription { Self::descriptor_static() } - fn new() -> SingleSelectDescription { - SingleSelectDescription::new() + fn new() -> SingleSelectTypeOption { + SingleSelectTypeOption::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -182,29 +182,29 @@ impl ::protobuf::Message for SingleSelectDescription { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "options", - |m: &SingleSelectDescription| { &m.options }, - |m: &mut SingleSelectDescription| { &mut m.options }, + |m: &SingleSelectTypeOption| { &m.options }, + |m: &mut SingleSelectTypeOption| { &mut m.options }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "disable_color", - |m: &SingleSelectDescription| { &m.disable_color }, - |m: &mut SingleSelectDescription| { &mut m.disable_color }, + |m: &SingleSelectTypeOption| { &m.disable_color }, + |m: &mut SingleSelectTypeOption| { &mut m.disable_color }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SingleSelectDescription", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SingleSelectTypeOption", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static SingleSelectDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SingleSelectDescription::new) + fn default_instance() -> &'static SingleSelectTypeOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SingleSelectTypeOption::new) } } -impl ::protobuf::Clear for SingleSelectDescription { +impl ::protobuf::Clear for SingleSelectTypeOption { fn clear(&mut self) { self.options.clear(); self.disable_color = false; @@ -212,20 +212,20 @@ impl ::protobuf::Clear for SingleSelectDescription { } } -impl ::std::fmt::Debug for SingleSelectDescription { +impl ::std::fmt::Debug for SingleSelectTypeOption { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { +impl ::protobuf::reflect::ProtobufValue for SingleSelectTypeOption { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct MultiSelectDescription { +pub struct MultiSelectTypeOption { // message fields pub options: ::protobuf::RepeatedField, pub disable_color: bool, @@ -234,14 +234,14 @@ pub struct MultiSelectDescription { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a MultiSelectDescription { - fn default() -> &'a MultiSelectDescription { - ::default_instance() +impl<'a> ::std::default::Default for &'a MultiSelectTypeOption { + fn default() -> &'a MultiSelectTypeOption { + ::default_instance() } } -impl MultiSelectDescription { - pub fn new() -> MultiSelectDescription { +impl MultiSelectTypeOption { + pub fn new() -> MultiSelectTypeOption { ::std::default::Default::default() } @@ -286,7 +286,7 @@ impl MultiSelectDescription { } } -impl ::protobuf::Message for MultiSelectDescription { +impl ::protobuf::Message for MultiSelectTypeOption { fn is_initialized(&self) -> bool { for v in &self.options { if !v.is_initialized() { @@ -373,8 +373,8 @@ impl ::protobuf::Message for MultiSelectDescription { Self::descriptor_static() } - fn new() -> MultiSelectDescription { - MultiSelectDescription::new() + fn new() -> MultiSelectTypeOption { + MultiSelectTypeOption::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -383,29 +383,29 @@ impl ::protobuf::Message for MultiSelectDescription { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "options", - |m: &MultiSelectDescription| { &m.options }, - |m: &mut MultiSelectDescription| { &mut m.options }, + |m: &MultiSelectTypeOption| { &m.options }, + |m: &mut MultiSelectTypeOption| { &mut m.options }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "disable_color", - |m: &MultiSelectDescription| { &m.disable_color }, - |m: &mut MultiSelectDescription| { &mut m.disable_color }, + |m: &MultiSelectTypeOption| { &m.disable_color }, + |m: &mut MultiSelectTypeOption| { &mut m.disable_color }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "MultiSelectDescription", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MultiSelectTypeOption", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static MultiSelectDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(MultiSelectDescription::new) + fn default_instance() -> &'static MultiSelectTypeOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MultiSelectTypeOption::new) } } -impl ::protobuf::Clear for MultiSelectDescription { +impl ::protobuf::Clear for MultiSelectTypeOption { fn clear(&mut self) { self.options.clear(); self.disable_color = false; @@ -413,13 +413,13 @@ impl ::protobuf::Clear for MultiSelectDescription { } } -impl ::std::fmt::Debug for MultiSelectDescription { +impl ::std::fmt::Debug for MultiSelectTypeOption { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { +impl ::protobuf::reflect::ProtobufValue for MultiSelectTypeOption { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -669,12 +669,12 @@ impl ::protobuf::reflect::ProtobufValue for SelectOption { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x1bselection_description.proto\"g\n\x17SingleSelectDescription\x12'\n\ + \n\x1bselection_type_option.proto\"f\n\x16SingleSelectTypeOption\x12'\n\ \x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdis\ - able_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"f\n\x16MultiSelectDesc\ - ription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07optio\ - ns\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cS\ - electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ + able_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"e\n\x15MultiSelectType\ + Option\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07option\ + s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cSe\ + lectOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ \x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05c\ olorb\x06proto3\ "; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs index ca2d720e14..2bedb36f63 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs @@ -24,7 +24,7 @@ // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct RichTextDescription { +pub struct RichTextTypeOption { // message fields pub format: ::std::string::String, // special fields @@ -32,14 +32,14 @@ pub struct RichTextDescription { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a RichTextDescription { - fn default() -> &'a RichTextDescription { - ::default_instance() +impl<'a> ::std::default::Default for &'a RichTextTypeOption { + fn default() -> &'a RichTextTypeOption { + ::default_instance() } } -impl RichTextDescription { - pub fn new() -> RichTextDescription { +impl RichTextTypeOption { + pub fn new() -> RichTextTypeOption { ::std::default::Default::default() } @@ -70,7 +70,7 @@ impl RichTextDescription { } } -impl ::protobuf::Message for RichTextDescription { +impl ::protobuf::Message for RichTextTypeOption { fn is_initialized(&self) -> bool { true } @@ -136,8 +136,8 @@ impl ::protobuf::Message for RichTextDescription { Self::descriptor_static() } - fn new() -> RichTextDescription { - RichTextDescription::new() + fn new() -> RichTextTypeOption { + RichTextTypeOption::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -146,45 +146,45 @@ impl ::protobuf::Message for RichTextDescription { 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 }, + |m: &RichTextTypeOption| { &m.format }, + |m: &mut RichTextTypeOption| { &mut m.format }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RichTextDescription", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RichTextTypeOption", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static RichTextDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RichTextDescription::new) + fn default_instance() -> &'static RichTextTypeOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RichTextTypeOption::new) } } -impl ::protobuf::Clear for RichTextDescription { +impl ::protobuf::Clear for RichTextTypeOption { fn clear(&mut self) { self.format.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for RichTextDescription { +impl ::std::fmt::Debug for RichTextTypeOption { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for RichTextDescription { +impl ::protobuf::reflect::ProtobufValue for RichTextTypeOption { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x16text_description.proto\"-\n\x13RichTextDescription\x12\x16\n\x06fo\ - rmat\x18\x01\x20\x01(\tR\x06formatb\x06proto3\ + \n\x16text_description.proto\",\n\x12RichTextTypeOption\x12\x16\n\x06for\ + mat\x18\x01\x20\x01(\tR\x06formatb\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/checkbox_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_type_option.proto similarity index 61% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_type_option.proto index 7c14ebc075..df721337c7 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_type_option.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -message CheckboxDescription { +message CheckboxTypeOption { bool is_selected = 1; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index be25f80f3b..da1d193b21 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -3,7 +3,7 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; GridDidCreateBlock = 11; - BlockDidUpdateRow = 20; + DidUpdateRow = 20; GridDidUpdateCells = 30; - GridDidUpdateFields = 40; + DidUpdateFields = 40; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto similarity index 89% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto index 9fe4c4acfd..be42570348 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -message DateDescription { +message DateTypeOption { DateFormat date_format = 1; TimeFormat time_format = 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 6c39e618f5..9a2177b6f4 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 @@ -4,7 +4,9 @@ enum GridEvent { GetGridData = 0; GetGridBlocks = 1; GetFields = 10; - CreateRow = 11; - GetRow = 12; - UpdateCell = 20; + UpdateField = 11; + CreateField = 12; + CreateRow = 21; + GetRow = 22; + UpdateCell = 30; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto similarity index 88% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto index 760f6623c4..8057b0c4a6 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -message NumberDescription { +message NumberTypeOption { NumberFormat format = 1; uint32 scale = 2; string symbol = 3; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto similarity index 78% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index 7f3ee25661..9fdfc34e9b 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -message SingleSelectDescription { +message SingleSelectTypeOption { repeated SelectOption options = 1; bool disable_color = 2; } -message MultiSelectDescription { +message MultiSelectTypeOption { repeated SelectOption options = 1; bool disable_color = 2; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto index c4ee8f8de6..67cfb438ea 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -message RichTextDescription { +message RichTextTypeOption { string format = 1; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 4a73ccd1b1..d6289dc958 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -6,7 +6,8 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RowMeta, RowMetaChangeset, RowOrder, + FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta, + RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{ @@ -186,9 +187,9 @@ impl GridBlockMetaEditorManager { } async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { - let block_id: GridBlockId = block_id.into(); - send_dart_notification(&self.grid_id, GridNotification::BlockDidUpdateRow) - .payload(block_id) + let block_order: GridBlockOrder = block_id.into(); + send_dart_notification(&self.grid_id, GridNotification::DidUpdateRow) + .payload(block_order) .send(); Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs deleted file mode 100644 index 6812d2c39d..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs +++ /dev/null @@ -1,137 +0,0 @@ -use crate::services::cell::*; -use crate::services::field::TypeOptionsBuilder; -use flowy_grid_data_model::entities::FieldType; - -// Text -#[derive(Default)] -pub struct RichTextTypeOptionsBuilder(RichTextDescription); - -impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Number -#[derive(Default)] -pub struct NumberTypeOptionsBuilder(NumberDescription); - -impl NumberTypeOptionsBuilder { - pub fn name(mut self, name: &str) -> Self { - self.0.name = name.to_string(); - self - } - - pub fn set_format(mut self, format: NumberFormat) -> Self { - self.0.set_format(format); - self - } - - pub fn scale(mut self, scale: u32) -> Self { - self.0.scale = scale; - self - } - - pub fn positive(mut self, positive: bool) -> Self { - self.0.sign_positive = positive; - self - } -} - -impl TypeOptionsBuilder for NumberTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Date -#[derive(Default)] -pub struct DateTypeOptionsBuilder(DateDescription); -impl DateTypeOptionsBuilder { - pub fn date_format(mut self, date_format: DateFormat) -> Self { - self.0.date_format = date_format; - self - } - - pub fn time_format(mut self, time_format: TimeFormat) -> Self { - self.0.time_format = time_format; - self - } -} -impl TypeOptionsBuilder for DateTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Single Select -#[derive(Default)] -pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); - -impl SingleSelectTypeOptionsBuilder { - pub fn option(mut self, opt: SelectOption) -> Self { - self.0.options.push(opt); - self - } -} -impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Multi Select -#[derive(Default)] -pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); - -impl MultiSelectTypeOptionsBuilder { - pub fn option(mut self, opt: SelectOption) -> Self { - self.0.options.push(opt); - self - } -} - -impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Checkbox -#[derive(Default)] -pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); -impl CheckboxTypeOptionsBuilder { - pub fn set_selected(mut self, is_selected: bool) -> Self { - self.0.is_selected = is_selected; - self - } -} -impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs deleted file mode 100644 index faadd45f8c..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod checkbox_description; -mod date_description; -mod number_description; -mod selection_description; -mod text_description; - -pub use checkbox_description::*; -pub use date_description::*; -pub use number_description::*; -pub use selection_description::*; -pub use text_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs deleted file mode 100644 index 0c28db7789..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod builder; -mod description; - -pub use builder::*; -pub use description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 15f5b805d9..14206f9254 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -48,7 +48,7 @@ impl FieldBuilder { assert_eq!(self.field_meta.field_type, self.type_options_builder.field_type()); let type_options = self.type_options_builder.build(); - self.field_meta.type_options = type_options; + self.field_meta.type_option = type_options; self.field_meta } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 50d069cf9b..61b5889e68 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,3 +1,5 @@ mod field_builder; +mod type_options; pub use field_builder::*; +pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs similarity index 69% rename from frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 87bd7f848c..da6d057c03 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,18 +1,38 @@ use crate::impl_from_and_to_type_option; +use crate::services::field::TypeOptionsBuilder; use crate::services::row::CellDataSerde; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; +#[derive(Default)] +pub struct CheckboxTypeOptionsBuilder(CheckboxTypeOption); +impl CheckboxTypeOptionsBuilder { + pub fn set_selected(mut self, is_selected: bool) -> Self { + self.0.is_selected = is_selected; + self + } +} + +impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] -pub struct CheckboxDescription { +pub struct CheckboxTypeOption { #[pb(index = 1)] pub is_selected: bool, } -impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); +impl_from_and_to_type_option!(CheckboxTypeOption, FieldType::Checkbox); -impl CellDataSerde for CheckboxDescription { +impl CellDataSerde for CheckboxTypeOption { fn deserialize_cell_data(&self, data: String) -> String { data } @@ -41,12 +61,12 @@ fn string_to_bool(bool_str: &str) -> bool { #[cfg(test)] mod tests { - use crate::services::cell::CheckboxDescription; + use crate::services::cell::CheckboxTypeOption; use crate::services::row::CellDataSerde; #[test] fn checkout_box_description_test() { - let description = CheckboxDescription::default(); + let description = CheckboxTypeOption::default(); assert_eq!(description.serialize_cell_data("true").unwrap(), "1".to_owned()); assert_eq!(description.serialize_cell_data("1").unwrap(), "1".to_owned()); assert_eq!(description.serialize_cell_data("yes").unwrap(), "1".to_owned()); diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs similarity index 87% rename from frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 0ad2e3f6a9..8c8fec6a86 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -8,20 +8,21 @@ use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; +use crate::services::field::TypeOptionsBuilder; use strum_macros::EnumIter; // Date #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct DateDescription { +pub struct DateTypeOption { #[pb(index = 1)] pub date_format: DateFormat, #[pb(index = 2)] pub time_format: TimeFormat, } -impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); +impl_from_and_to_type_option!(DateTypeOption, FieldType::DateTime); -impl DateDescription { +impl DateTypeOption { #[allow(dead_code)] fn today_from_timestamp(&self, timestamp: i64) -> String { let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); @@ -38,7 +39,7 @@ impl DateDescription { } } -impl CellDataSerde for DateDescription { +impl CellDataSerde for DateTypeOption { fn deserialize_cell_data(&self, data: String) -> String { match data.parse::() { Ok(timestamp) => { @@ -61,6 +62,29 @@ impl CellDataSerde for DateDescription { } } +#[derive(Default)] +pub struct DateTypeOptionsBuilder(DateTypeOption); +impl DateTypeOptionsBuilder { + pub fn date_format(mut self, date_format: DateFormat) -> Self { + self.0.date_format = date_format; + self + } + + pub fn time_format(mut self, time_format: TimeFormat) -> Self { + self.0.time_format = time_format; + self + } +} +impl TypeOptionsBuilder for DateTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + #[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] pub enum DateFormat { Local = 0, @@ -145,13 +169,13 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { - use crate::services::cell::{DateDescription, DateFormat, TimeFormat}; + use crate::services::cell::{DateFormat, DateTypeOption, TimeFormat}; use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] fn date_description_date_format_test() { - let mut description = DateDescription::default(); + let mut description = DateTypeOption::default(); let _timestamp = 1647251762; for date_format in DateFormat::iter() { @@ -203,7 +227,7 @@ mod tests { #[test] fn date_description_time_format_test() { - let mut description = DateDescription::default(); + let mut description = DateTypeOption::default(); for time_format in TimeFormat::iter() { description.time_format = time_format; match time_format { @@ -234,7 +258,7 @@ mod tests { #[test] #[should_panic] fn date_description_invalid_data_test() { - let description = DateDescription::default(); + let description = DateTypeOption::default(); description.serialize_cell_data("he").unwrap(); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs new file mode 100644 index 0000000000..51d06fff19 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs @@ -0,0 +1,11 @@ +mod checkbox_type_option; +mod date_type_option; +mod number_type_option; +mod selection_type_option; +mod text_description; + +pub use checkbox_type_option::*; +pub use date_type_option::*; +pub use number_type_option::*; +pub use selection_type_option::*; +pub use text_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs similarity index 86% rename from frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index c3468786df..64783cda2b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -9,6 +9,7 @@ use rust_decimal::Decimal; use rusty_money::iso::{Currency, CNY, EUR, USD}; use serde::{Deserialize, Serialize}; +use crate::services::field::TypeOptionsBuilder; use std::str::FromStr; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -17,6 +18,108 @@ lazy_static! { static ref STRIP_SYMBOL: Vec = make_strip_symbol(); } +#[derive(Default)] +pub struct NumberTypeOptionsBuilder(NumberTypeOption); + +impl NumberTypeOptionsBuilder { + pub fn name(mut self, name: &str) -> Self { + self.0.name = name.to_string(); + self + } + + pub fn set_format(mut self, format: NumberFormat) -> Self { + self.0.set_format(format); + self + } + + pub fn scale(mut self, scale: u32) -> Self { + self.0.scale = scale; + self + } + + pub fn positive(mut self, positive: bool) -> Self { + self.0.sign_positive = positive; + self + } +} + +impl TypeOptionsBuilder for NumberTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Number +#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] +pub struct NumberTypeOption { + #[pb(index = 1)] + pub format: NumberFormat, + + #[pb(index = 2)] + pub scale: u32, + + #[pb(index = 3)] + pub symbol: String, + + #[pb(index = 4)] + pub sign_positive: bool, + + #[pb(index = 5)] + pub name: String, +} +impl_from_and_to_type_option!(NumberTypeOption, FieldType::Number); + +impl std::default::Default for NumberTypeOption { + fn default() -> Self { + let format = NumberFormat::default(); + let symbol = format.symbol(); + NumberTypeOption { + format, + scale: 0, + symbol, + sign_positive: true, + name: "Number".to_string(), + } + } +} + +impl NumberTypeOption { + pub fn set_format(&mut self, format: NumberFormat) { + self.format = format; + self.symbol = format.symbol(); + } + + fn decimal_from_str(&self, s: &str) -> Decimal { + let mut decimal = Decimal::from_str(s).unwrap_or_else(|_| Decimal::zero()); + match decimal.set_scale(self.scale) { + Ok(_) => {} + Err(e) => { + tracing::error!("Set decimal scale failed: {:?}", e); + } + } + decimal.set_sign_positive(self.sign_positive); + decimal + } + + fn money_from_str(&self, s: &str, currency: &'static Currency) -> String { + let decimal = self.decimal_from_str(s); + let money = rusty_money::Money::from_decimal(decimal, currency); + money.to_string() + } + + fn strip_symbol(&self, s: &str) -> String { + let mut s = String::from(s); + if !s.chars().all(char::is_numeric) { + s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); + } + s + } +} + #[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] pub enum NumberFormat { Number = 0, @@ -52,74 +155,7 @@ impl NumberFormat { } } -// Number -#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] -pub struct NumberDescription { - #[pb(index = 1)] - pub format: NumberFormat, - - #[pb(index = 2)] - pub scale: u32, - - #[pb(index = 3)] - pub symbol: String, - - #[pb(index = 4)] - pub sign_positive: bool, - - #[pb(index = 5)] - pub name: String, -} -impl_from_and_to_type_option!(NumberDescription, FieldType::Number); - -impl std::default::Default for NumberDescription { - fn default() -> Self { - let format = NumberFormat::default(); - let symbol = format.symbol(); - NumberDescription { - format, - scale: 0, - symbol, - sign_positive: true, - name: "Number".to_string(), - } - } -} - -impl NumberDescription { - pub fn set_format(&mut self, format: NumberFormat) { - self.format = format; - self.symbol = format.symbol(); - } - - fn decimal_from_str(&self, s: &str) -> Decimal { - let mut decimal = Decimal::from_str(s).unwrap_or_else(|_| Decimal::zero()); - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - decimal.set_sign_positive(self.sign_positive); - decimal - } - - fn money_from_str(&self, s: &str, currency: &'static Currency) -> String { - let decimal = self.decimal_from_str(s); - let money = rusty_money::Money::from_decimal(decimal, currency); - money.to_string() - } - - fn strip_symbol(&self, s: &str) -> String { - let mut s = String::from(s); - if !s.chars().all(char::is_numeric) { - s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); - } - s - } -} - -impl CellDataSerde for NumberDescription { +impl CellDataSerde for NumberTypeOption { fn deserialize_cell_data(&self, data: String) -> String { match self.format { NumberFormat::Number => data, @@ -149,13 +185,13 @@ fn make_strip_symbol() -> Vec { #[cfg(test)] mod tests { - use crate::services::cell::{NumberDescription, NumberFormat}; + use crate::services::cell::{NumberFormat, NumberTypeOption}; use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] fn number_description_test() { - let mut description = NumberDescription::default(); + let mut description = NumberTypeOption::default(); assert_eq!(description.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned()); assert_eq!(description.serialize_cell_data("$18,443").unwrap(), "18443".to_owned()); assert_eq!(description.serialize_cell_data("€18.443").unwrap(), "18443".to_owned()); @@ -193,7 +229,7 @@ mod tests { #[test] fn number_description_scale_test() { - let mut description = NumberDescription { + let mut description = NumberTypeOption { scale: 1, ..Default::default() }; @@ -231,7 +267,7 @@ mod tests { #[test] fn number_description_sign_test() { - let mut description = NumberDescription { + let mut description = NumberTypeOption { sign_positive: false, ..Default::default() }; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs similarity index 71% rename from frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 75a2d9feb2..af5e58119f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,4 +1,5 @@ use crate::impl_from_and_to_type_option; +use crate::services::field::TypeOptionsBuilder; use crate::services::row::CellDataSerde; use crate::services::util::*; use flowy_derive::ProtoBuf; @@ -12,16 +13,16 @@ pub const SELECTION_IDS_SEPARATOR: &str = ","; // Single select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct SingleSelectDescription { +pub struct SingleSelectTypeOption { #[pb(index = 1)] pub options: Vec, #[pb(index = 2)] pub disable_color: bool, } -impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); +impl_from_and_to_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); -impl CellDataSerde for SingleSelectDescription { +impl CellDataSerde for SingleSelectTypeOption { fn deserialize_cell_data(&self, data: String) -> String { data } @@ -31,17 +32,36 @@ impl CellDataSerde for SingleSelectDescription { } } +#[derive(Default)] +pub struct SingleSelectTypeOptionsBuilder(SingleSelectTypeOption); + +impl SingleSelectTypeOptionsBuilder { + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} +impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + // Multiple select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct MultiSelectDescription { +pub struct MultiSelectTypeOption { #[pb(index = 1)] pub options: Vec, #[pb(index = 2)] pub disable_color: bool, } -impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); -impl CellDataSerde for MultiSelectDescription { +impl_from_and_to_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); +impl CellDataSerde for MultiSelectTypeOption { fn deserialize_cell_data(&self, data: String) -> String { data } @@ -51,6 +71,25 @@ impl CellDataSerde for MultiSelectDescription { } } +#[derive(Default)] +pub struct MultiSelectTypeOptionsBuilder(MultiSelectTypeOption); +impl MultiSelectTypeOptionsBuilder { + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} + +impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + fn single_select_option_id_from_data(data: String) -> FlowyResult { let select_option_ids = select_option_ids(data)?; if select_option_ids.is_empty() { @@ -112,13 +151,13 @@ impl SelectOption { #[cfg(test)] mod tests { - use crate::services::cell::{MultiSelectDescription, SingleSelectDescription}; + use crate::services::cell::{MultiSelectDescription, SingleSelectTypeOption}; use crate::services::row::CellDataSerde; #[test] #[should_panic] fn selection_description_test() { - let description = SingleSelectDescription::default(); + let description = SingleSelectTypeOption::default(); assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); let description = MultiSelectDescription::default(); diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_description.rs similarity index 60% rename from frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/text_description.rs index 539b82402c..9b6b988fc0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_description.rs @@ -1,19 +1,33 @@ use crate::impl_from_and_to_type_option; use crate::services::row::CellDataSerde; +use crate::services::field::TypeOptionsBuilder; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; +#[derive(Default)] +pub struct RichTextTypeOptionsBuilder(RichTextTypeOption); + +impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct RichTextDescription { +pub struct RichTextTypeOption { #[pb(index = 1)] pub format: String, } -impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); +impl_from_and_to_type_option!(RichTextTypeOption, FieldType::RichText); -impl CellDataSerde for RichTextDescription { +impl CellDataSerde for RichTextTypeOption { fn deserialize_cell_data(&self, data: String) -> String { data } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 7bcbe39830..80768c5251 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -16,6 +16,7 @@ use crate::services::row::{ make_grid_block_from_block_metas, make_grid_blocks, make_row_meta_from_context, make_rows_from_row_metas, serialize_cell_data, CreateRowMetaBuilder, CreateRowMetaPayload, GridBlockMetaData, }; +use flowy_grid_data_model::parser::CreateFieldParams; use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; @@ -54,23 +55,25 @@ impl ClientGridEditor { })) } - pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?; + pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_field(params)?)).await?; let _ = self.notify_did_update_fields().await?; Ok(()) } - pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool { - self.pad.read().await.contain_field(&field_meta.id) + pub async fn contain_field(&self, field_id: &str) -> bool { + self.pad.read().await.contain_field(field_id) } pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?; + let _ = self.notify_did_update_fields().await?; Ok(()) } pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; + let _ = self.notify_did_update_fields().await?; Ok(()) } @@ -293,7 +296,7 @@ impl ClientGridEditor { async fn notify_did_update_fields(&self) -> FlowyResult<()> { let field_metas = self.get_field_metas(None).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); - send_dart_notification(&self.grid_id, GridNotification::GridDidUpdateFields) + send_dart_notification(&self.grid_id, GridNotification::DidUpdateFields) .payload(repeated_field) .send(); Ok(()) diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index f8b0422685..d3eb2d2857 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,7 +1,6 @@ mod util; pub mod block_meta_editor; -pub mod cell; pub mod field; pub mod grid_editor; pub mod kv_persistence; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs index 148b5254ba..3d1c1939d7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs @@ -1,4 +1,4 @@ -use crate::services::cell::*; +use crate::services::field::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; @@ -10,23 +10,23 @@ pub trait CellDataSerde { #[allow(dead_code)] pub fn serialize_cell_data(data: &str, field: &FieldMeta) -> Result { match field.field_type { - FieldType::RichText => RichTextDescription::from(field).serialize_cell_data(data), - FieldType::Number => NumberDescription::from(field).serialize_cell_data(data), - FieldType::DateTime => DateDescription::from(field).serialize_cell_data(data), - FieldType::SingleSelect => SingleSelectDescription::from(field).serialize_cell_data(data), - FieldType::MultiSelect => MultiSelectDescription::from(field).serialize_cell_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).serialize_cell_data(data), + FieldType::RichText => RichTextTypeOption::from(field).serialize_cell_data(data), + FieldType::Number => NumberTypeOption::from(field).serialize_cell_data(data), + FieldType::DateTime => DateTypeOption::from(field).serialize_cell_data(data), + FieldType::SingleSelect => SingleSelectTypeOption::from(field).serialize_cell_data(data), + FieldType::MultiSelect => MultiSelectTypeOption::from(field).serialize_cell_data(data), + FieldType::Checkbox => CheckboxTypeOption::from(field).serialize_cell_data(data), } } pub fn deserialize_cell_data(data: String, field: &FieldMeta) -> Result { let s = match field.field_type { - FieldType::RichText => RichTextDescription::from(field).deserialize_cell_data(data), - FieldType::Number => NumberDescription::from(field).deserialize_cell_data(data), - FieldType::DateTime => DateDescription::from(field).deserialize_cell_data(data), - FieldType::SingleSelect => SingleSelectDescription::from(field).deserialize_cell_data(data), - FieldType::MultiSelect => MultiSelectDescription::from(field).deserialize_cell_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).deserialize_cell_data(data), + FieldType::RichText => RichTextTypeOption::from(field).deserialize_cell_data(data), + FieldType::Number => NumberTypeOption::from(field).deserialize_cell_data(data), + FieldType::DateTime => DateTypeOption::from(field).deserialize_cell_data(data), + FieldType::SingleSelect => SingleSelectTypeOption::from(field).deserialize_cell_data(data), + FieldType::MultiSelect => MultiSelectTypeOption::from(field).deserialize_cell_data(data), + FieldType::Checkbox => CheckboxTypeOption::from(field).deserialize_cell_data(data), }; Ok(s) } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 1c10eb1726..9349854433 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,4 +1,3 @@ -use crate::services::cell::*; use crate::services::field::*; use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; use flowy_sync::client_grid::GridBuilder; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index abc00d5fb2..803c2409a9 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,9 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use chrono::NaiveDateTime; -use flowy_grid::services::cell::*; +use flowy_grid::services::field::{ + MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, +}; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, @@ -10,23 +12,22 @@ use flowy_grid_data_model::entities::{ #[tokio::test] async fn grid_create_field() { let mut test = GridEditorTest::new().await; - let text_field = create_text_field(); - let single_select_field = create_single_select_field(); - + let (text_field_params, text_field_meta) = create_text_field(&test.grid_id); + let (single_select_params, single_select_field) = create_single_select_field(&test.grid_id); let scripts = vec![ CreateField { - field_meta: text_field.clone(), + params: text_field_params, }, AssertFieldEqual { field_index: test.field_count, - field_meta: text_field, + field_meta: text_field_meta, }, ]; test.run_scripts(scripts).await; let scripts = vec![ CreateField { - field_meta: single_select_field.clone(), + params: single_select_params, }, AssertFieldEqual { field_index: test.field_count, @@ -39,16 +40,12 @@ async fn grid_create_field() { #[tokio::test] async fn grid_create_duplicate_field() { let mut test = GridEditorTest::new().await; - let text_field = create_text_field(); + let (params, _) = create_text_field(&test.grid_id); let field_count = test.field_count; let expected_field_count = field_count + 1; let scripts = vec![ - CreateField { - field_meta: text_field.clone(), - }, - CreateField { - field_meta: text_field.clone(), - }, + CreateField { params: params.clone() }, + CreateField { params }, AssertFieldCount(expected_field_count), ]; test.run_scripts(scripts).await; @@ -57,9 +54,10 @@ async fn grid_create_duplicate_field() { #[tokio::test] async fn grid_update_field_with_empty_change() { let mut test = GridEditorTest::new().await; - let single_select_field = create_single_select_field(); + let (params, field_meta) = create_single_select_field(&test.grid_id); let changeset = FieldChangeset { - field_id: single_select_field.id.clone(), + field_id: field_meta.id.clone(), + grid_id: test.grid_id.clone(), name: None, desc: None, field_type: None, @@ -70,13 +68,11 @@ async fn grid_update_field_with_empty_change() { }; let scripts = vec![ - CreateField { - field_meta: single_select_field.clone(), - }, + CreateField { params }, UpdateField { changeset }, AssertFieldEqual { field_index: test.field_count, - field_meta: single_select_field, + field_meta, }, ]; test.run_scripts(scripts).await; @@ -85,13 +81,14 @@ async fn grid_update_field_with_empty_change() { #[tokio::test] async fn grid_update_field() { let mut test = GridEditorTest::new().await; - let single_select_field = create_single_select_field(); + let (single_select_params, single_select_field) = create_single_select_field(&test.grid_id); let mut cloned_field = single_select_field.clone(); - let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); + let mut single_select_type_options = SingleSelectTypeOption::from(&single_select_field); single_select_type_options.options.push(SelectOption::new("Unknown")); let changeset = FieldChangeset { field_id: single_select_field.id.clone(), + grid_id: test.grid_id.clone(), name: None, desc: None, field_type: None, @@ -103,11 +100,11 @@ async fn grid_update_field() { cloned_field.frozen = true; cloned_field.width = 1000; - cloned_field.type_options = single_select_type_options.into(); + cloned_field.type_option = single_select_type_options.into(); let scripts = vec![ CreateField { - field_meta: single_select_field.clone(), + params: single_select_params, }, UpdateField { changeset }, AssertFieldEqual { @@ -122,11 +119,9 @@ async fn grid_update_field() { async fn grid_delete_field() { let mut test = GridEditorTest::new().await; let expected_field_count = test.field_count; - let text_field = create_text_field(); + let (text_params, text_field) = create_text_field(&test.grid_id); let scripts = vec![ - CreateField { - field_meta: text_field.clone(), - }, + CreateField { params: text_params }, DeleteField { field_meta: text_field }, AssertFieldCount(expected_field_count), ]; @@ -258,13 +253,13 @@ async fn grid_row_add_cells_test() { builder.add_cell(&field.id, data).unwrap(); } FieldType::SingleSelect => { - let description = SingleSelectDescription::from(field); + let description = SingleSelectTypeOption::from(field); let options = description.options.first().unwrap(); let data = description.serialize_cell_data(&options.id).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { - let description = MultiSelectDescription::from(field); + let description = MultiSelectTypeOption::from(field); let options = description .options .iter() @@ -387,11 +382,11 @@ async fn grid_cell_update() { FieldType::Number => "123".to_string(), FieldType::DateTime => "123".to_string(), FieldType::SingleSelect => { - let description = SingleSelectDescription::from(field_meta); + let description = SingleSelectTypeOption::from(field_meta); description.options.first().unwrap().id.clone() } FieldType::MultiSelect => { - let description = MultiSelectDescription::from(field_meta); + let description = MultiSelectTypeOption::from(field_meta); description.options.first().unwrap().id.clone() } FieldType::Checkbox => "1".to_string(), diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 0da0a911f1..fa25ef3e78 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,18 +1,17 @@ use bytes::Bytes; -use flowy_sync::client_grid::GridBuilder; -use std::collections::HashMap; - -use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, - RowMeta, RowMetaChangeset, RowOrder, + BuildGridContext, CellMetaChangeset, CreateFieldPayload, Field, FieldChangeset, FieldMeta, FieldType, + GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, }; +use flowy_grid_data_model::parser::CreateFieldParams; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; +use flowy_sync::client_grid::GridBuilder; use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; +use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; use strum::EnumCount; @@ -20,7 +19,7 @@ use tokio::time::sleep; pub enum EditorScript { CreateField { - field_meta: FieldMeta, + params: CreateFieldParams, }, UpdateField { changeset: FieldChangeset, @@ -121,11 +120,12 @@ impl GridEditorTest { let _cache = rev_manager.revision_cache().await; match script { - EditorScript::CreateField { field_meta } => { - if !self.editor.contain_field(&field_meta).await { + EditorScript::CreateField { params } => { + if !self.editor.contain_field(¶ms.field.id).await { self.field_count += 1; } - self.editor.create_field(field_meta).await.unwrap(); + + self.editor.create_field(params).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); assert_eq!(self.field_count, self.field_metas.len()); } @@ -134,7 +134,7 @@ impl GridEditorTest { self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } EditorScript::DeleteField { field_meta } => { - if self.editor.contain_field(&field_meta).await { + if self.editor.contain_field(&field_meta.id).await { self.field_count -= 1; } @@ -247,24 +247,64 @@ async fn get_row_metas(editor: &Arc) -> Vec> { .row_metas } -pub fn create_text_field() -> FieldMeta { - FieldBuilder::new(RichTextTypeOptionsBuilder::default()) +pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { + let field_meta = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) .field_type(FieldType::RichText) - .build() + .build(); + + let cloned_field_meta = field_meta.clone(); + + let field = Field { + id: field_meta.id, + name: field_meta.name, + desc: field_meta.desc, + field_type: field_meta.field_type, + frozen: field_meta.frozen, + visibility: field_meta.visibility, + width: field_meta.width, + }; + + let params = CreateFieldParams { + grid_id: grid_id.to_owned(), + field, + type_option_data: field_meta.type_option.as_bytes().to_vec(), + start_field_id: None, + }; + (params, cloned_field_meta) } -pub fn create_single_select_field() -> FieldMeta { +pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); - FieldBuilder::new(single_select) + let field_meta = FieldBuilder::new(single_select) .name("Name") .visibility(true) .field_type(FieldType::SingleSelect) - .build() + .build(); + + let cloned_field_meta = field_meta.clone(); + + let field = Field { + id: field_meta.id, + name: field_meta.name, + desc: field_meta.desc, + field_type: field_meta.field_type, + frozen: field_meta.frozen, + visibility: field_meta.visibility, + width: field_meta.width, + }; + + let params = CreateFieldParams { + grid_id: grid_id.to_owned(), + field, + type_option_data: field_meta.type_option.as_bytes().to_vec(), + start_field_id: None, + }; + (params, cloned_field_meta) } fn make_template_1_grid() -> BuildGridContext { diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index bccc0fefd9..d3e5f2e909 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -88,14 +88,20 @@ pub enum ErrorCode { UserNotExist = 312, #[display(fmt = "Text is too long")] TextTooLong = 400, - #[display(fmt = "Grid block id is empty")] - BlockIdIsEmpty = 401, - #[display(fmt = "Row id is empty")] - RowIdIsEmpty = 402, + #[display(fmt = "Grid id is empty")] - GridIdIsEmpty = 403, + GridIdIsEmpty = 410, + #[display(fmt = "Grid block id is empty")] + BlockIdIsEmpty = 420, + #[display(fmt = "Row id is empty")] + RowIdIsEmpty = 430, + #[display(fmt = "Field id is empty")] + FieldIdIsEmpty = 440, + #[display(fmt = "Field's type option should not be empty")] + TypeOptionIsEmpty = 441, + #[display(fmt = "Invalid data")] - InvalidData = 404, + InvalidData = 500, } impl ErrorCode { diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index 63a645ea6c..ffe8d5e0bc 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -57,10 +57,12 @@ pub enum ErrorCode { UserIdInvalid = 311, UserNotExist = 312, TextTooLong = 400, - BlockIdIsEmpty = 401, - RowIdIsEmpty = 402, - GridIdIsEmpty = 403, - InvalidData = 404, + GridIdIsEmpty = 410, + BlockIdIsEmpty = 420, + RowIdIsEmpty = 430, + FieldIdIsEmpty = 440, + TypeOptionIsEmpty = 441, + InvalidData = 500, } impl ::protobuf::ProtobufEnum for ErrorCode { @@ -102,10 +104,12 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 311 => ::std::option::Option::Some(ErrorCode::UserIdInvalid), 312 => ::std::option::Option::Some(ErrorCode::UserNotExist), 400 => ::std::option::Option::Some(ErrorCode::TextTooLong), - 401 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty), - 402 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), - 403 => ::std::option::Option::Some(ErrorCode::GridIdIsEmpty), - 404 => ::std::option::Option::Some(ErrorCode::InvalidData), + 410 => ::std::option::Option::Some(ErrorCode::GridIdIsEmpty), + 420 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty), + 430 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), + 440 => ::std::option::Option::Some(ErrorCode::FieldIdIsEmpty), + 441 => ::std::option::Option::Some(ErrorCode::TypeOptionIsEmpty), + 500 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None } } @@ -144,9 +148,11 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::UserIdInvalid, ErrorCode::UserNotExist, ErrorCode::TextTooLong, + ErrorCode::GridIdIsEmpty, ErrorCode::BlockIdIsEmpty, ErrorCode::RowIdIsEmpty, - ErrorCode::GridIdIsEmpty, + ErrorCode::FieldIdIsEmpty, + ErrorCode::TypeOptionIsEmpty, ErrorCode::InvalidData, ]; values @@ -176,7 +182,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xb7\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xe4\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\ \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\ @@ -193,10 +199,11 @@ static file_descriptor_proto_data: &'static [u8] = b"\ swordNotMatch\x10\xb3\x02\x12\x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\ \n\"UserNameContainForbiddenCharacters\x10\xb5\x02\x12\x14\n\x0fUserName\ IsEmpty\x10\xb6\x02\x12\x12\n\rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUs\ - erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x13\n\ - \x0eBlockIdIsEmpty\x10\x91\x03\x12\x11\n\x0cRowIdIsEmpty\x10\x92\x03\x12\ - \x12\n\rGridIdIsEmpty\x10\x93\x03\x12\x10\n\x0bInvalidData\x10\x94\x03b\ - \x06proto3\ + erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x12\n\rG\ + ridIdIsEmpty\x10\x9a\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\xa4\x03\x12\x11\ + \n\x0cRowIdIsEmpty\x10\xae\x03\x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\ + \x12\x16\n\x11TypeOptionIsEmpty\x10\xb9\x03\x12\x10\n\x0bInvalidData\x10\ + \xf4\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index f8b8acb8e6..1d3d6ed94c 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -33,8 +33,10 @@ enum ErrorCode { UserIdInvalid = 311; UserNotExist = 312; TextTooLong = 400; - BlockIdIsEmpty = 401; - RowIdIsEmpty = 402; - GridIdIsEmpty = 403; - InvalidData = 404; + GridIdIsEmpty = 410; + BlockIdIsEmpty = 420; + RowIdIsEmpty = 430; + FieldIdIsEmpty = 440; + TypeOptionIsEmpty = 441; + InvalidData = 500; } 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 e9a80c4be3..c421dcac64 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -178,6 +178,12 @@ pub struct GridBlockOrder { pub block_id: String, } +impl std::convert::From<&str> for GridBlockOrder { + fn from(s: &str) -> Self { + GridBlockOrder { block_id: s.to_owned() } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] @@ -284,6 +290,21 @@ pub struct CreateRowPayload { pub start_row_id: Option, } +#[derive(ProtoBuf, Default)] +pub struct CreateFieldPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field: Field, + + #[pb(index = 3)] + pub type_option_data: Vec, + + #[pb(index = 4, one_of)] + pub start_field_id: Option, +} + #[derive(ProtoBuf, Default)] pub struct QueryFieldPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 9ba374169c..9bfc977838 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -98,7 +98,7 @@ pub struct FieldMeta { pub width: i32, #[pb(index = 8)] - pub type_options: String, + pub type_option: String, } impl FieldMeta { @@ -111,7 +111,7 @@ impl FieldMeta { frozen: false, visibility: true, width: DEFAULT_FIELD_WIDTH, - type_options: Default::default(), + type_option: Default::default(), } } } @@ -121,25 +121,28 @@ pub struct FieldChangeset { #[pb(index = 1)] pub field_id: String, - #[pb(index = 2, one_of)] - pub name: Option, + #[pb(index = 2)] + pub grid_id: String, #[pb(index = 3, one_of)] - pub desc: Option, + pub name: Option, #[pb(index = 4, one_of)] - pub field_type: Option, + pub desc: Option, #[pb(index = 5, one_of)] - pub frozen: Option, + pub field_type: Option, #[pb(index = 6, one_of)] - pub visibility: Option, + pub frozen: Option, #[pb(index = 7, one_of)] - pub width: Option, + pub visibility: Option, #[pb(index = 8, one_of)] + pub width: Option, + + #[pb(index = 9, one_of)] pub type_options: Option, } diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid.rs b/shared-lib/flowy-grid-data-model/src/parser/grid.rs deleted file mode 100644 index 49a202cf70..0000000000 --- a/shared-lib/flowy-grid-data-model/src/parser/grid.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::entities::{ - CreateRowPayload, GridBlockOrder, QueryFieldPayload, QueryGridBlocksPayload, QueryRowPayload, RepeatedFieldOrder, -}; -use crate::parser::NonEmptyId; -use flowy_error_code::ErrorCode; - -#[derive(Default)] -pub struct CreateRowParams { - pub grid_id: String, - pub start_row_id: Option, -} - -impl TryInto for CreateRowPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - Ok(CreateRowParams { - grid_id: grid_id.0, - start_row_id: self.start_row_id, - }) - } -} - -#[derive(Default)] -pub struct QueryFieldParams { - pub grid_id: String, - pub field_orders: RepeatedFieldOrder, -} - -impl TryInto for QueryFieldPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - Ok(QueryFieldParams { - grid_id: grid_id.0, - field_orders: self.field_orders, - }) - } -} - -#[derive(Default)] -pub struct QueryGridBlocksParams { - pub grid_id: String, - pub block_orders: Vec, -} - -impl TryInto for QueryGridBlocksPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - Ok(QueryGridBlocksParams { - grid_id: grid_id.0, - block_orders: self.block_orders, - }) - } -} - -#[derive(Default)] -pub struct QueryRowParams { - pub grid_id: String, - pub block_id: String, - pub row_id: String, -} - -impl TryInto for QueryRowPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let block_id = NonEmptyId::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; - let row_id = NonEmptyId::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; - - Ok(QueryRowParams { - grid_id: grid_id.0, - block_id: block_id.0, - row_id: row_id.0, - }) - } -} diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs b/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs new file mode 100644 index 0000000000..bfcb802c22 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs @@ -0,0 +1,116 @@ +use crate::entities::{ + CreateFieldPayload, CreateRowPayload, Field, GridBlockOrder, QueryFieldPayload, QueryGridBlocksPayload, + QueryRowPayload, RepeatedFieldOrder, +}; +use crate::parser::NotEmptyUuid; +use flowy_error_code::ErrorCode; + +#[derive(Default)] +pub struct CreateRowParams { + pub grid_id: String, + pub start_row_id: Option, +} + +impl TryInto for CreateRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(CreateRowParams { + grid_id: grid_id.0, + start_row_id: self.start_row_id, + }) + } +} + +#[derive(Default)] +pub struct QueryFieldParams { + pub grid_id: String, + pub field_orders: RepeatedFieldOrder, +} + +impl TryInto for QueryFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryFieldParams { + grid_id: grid_id.0, + field_orders: self.field_orders, + }) + } +} + +#[derive(Default)] +pub struct QueryGridBlocksParams { + pub grid_id: String, + pub block_orders: Vec, +} + +impl TryInto for QueryGridBlocksPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryGridBlocksParams { + grid_id: grid_id.0, + block_orders: self.block_orders, + }) + } +} + +#[derive(Default)] +pub struct QueryRowParams { + pub grid_id: String, + pub block_id: String, + pub row_id: String, +} + +impl TryInto for QueryRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let block_id = NotEmptyUuid::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(QueryRowParams { + grid_id: grid_id.0, + block_id: block_id.0, + row_id: row_id.0, + }) + } +} + +#[derive(Default, Clone)] +pub struct CreateFieldParams { + pub grid_id: String, + pub field: Field, + pub type_option_data: Vec, + pub start_field_id: Option, +} + +impl TryInto for CreateFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let _ = NotEmptyUuid::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + + let start_field_id = match self.start_field_id { + None => None, + Some(id) => Some(NotEmptyUuid::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + }; + + if self.type_option_data.is_empty() { + return Err(ErrorCode::TypeOptionIsEmpty); + } + + Ok(CreateFieldParams { + grid_id: grid_id.0, + field: self.field, + type_option_data: self.type_option_data, + start_field_id, + }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/id.rs b/shared-lib/flowy-grid-data-model/src/parser/id.rs deleted file mode 100644 index 5dbe65cf04..0000000000 --- a/shared-lib/flowy-grid-data-model/src/parser/id.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[derive(Debug)] -pub struct NonEmptyId(pub String); - -impl NonEmptyId { - pub fn parse(s: String) -> Result { - if s.trim().is_empty() { - return Err(()); - } - - Ok(Self(s)) - } -} - -impl AsRef for NonEmptyId { - fn as_ref(&self) -> &str { - &self.0 - } -} diff --git a/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs b/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs new file mode 100644 index 0000000000..f2eb8423bb --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs @@ -0,0 +1,22 @@ +use uuid::Uuid; + +#[derive(Debug)] +pub struct NotEmptyUuid(pub String); + +impl NotEmptyUuid { + pub fn parse(s: String) -> Result { + debug_assert!(Uuid::parse_str(&s).is_ok()); + + if s.trim().is_empty() { + return Err(()); + } + + Ok(Self(s)) + } +} + +impl AsRef for NotEmptyUuid { + fn as_ref(&self) -> &str { + &self.0 + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/mod.rs b/shared-lib/flowy-grid-data-model/src/parser/mod.rs index ec81801043..710464f814 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/mod.rs @@ -1,5 +1,5 @@ -mod grid; -mod id; +mod grid_params; +mod id_parser; -pub use grid::*; -pub use id::*; +pub use grid_params::*; +pub use id_parser::*; 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 f947f70851..5a8dced09b 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 @@ -3401,6 +3401,346 @@ impl ::protobuf::reflect::ProtobufValue for CreateRowPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct CreateFieldPayload { + // message fields + pub grid_id: ::std::string::String, + pub field: ::protobuf::SingularPtrField, + pub type_option_data: ::std::vec::Vec, + // message oneof groups + pub one_of_start_field_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateFieldPayload { + fn default() -> &'a CreateFieldPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CreateFieldPayload_oneof_one_of_start_field_id { + start_field_id(::std::string::String), +} + +impl CreateFieldPayload { + pub fn new() -> CreateFieldPayload { + ::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()) + } + + // .Field field = 2; + + + pub fn get_field(&self) -> &Field { + self.field.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_field(&mut self) { + self.field.clear(); + } + + pub fn has_field(&self) -> bool { + self.field.is_some() + } + + // Param is passed by value, moved + pub fn set_field(&mut self, v: Field) { + self.field = ::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(&mut self) -> &mut Field { + if self.field.is_none() { + self.field.set_default(); + } + self.field.as_mut().unwrap() + } + + // Take field + pub fn take_field(&mut self) -> Field { + self.field.take().unwrap_or_else(|| Field::new()) + } + + // bytes type_option_data = 3; + + + pub fn get_type_option_data(&self) -> &[u8] { + &self.type_option_data + } + pub fn clear_type_option_data(&mut self) { + self.type_option_data.clear(); + } + + // Param is passed by value, moved + pub fn set_type_option_data(&mut self, v: ::std::vec::Vec) { + self.type_option_data = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec { + &mut self.type_option_data + } + + // Take field + pub fn take_type_option_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.type_option_data, ::std::vec::Vec::new()) + } + + // string start_field_id = 4; + + + pub fn get_start_field_id(&self) -> &str { + match self.one_of_start_field_id { + ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v)) => v, + _ => "", + } + } + pub fn clear_start_field_id(&mut self) { + self.one_of_start_field_id = ::std::option::Option::None; + } + + pub fn has_start_field_id(&self) -> bool { + match self.one_of_start_field_id { + ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_start_field_id(&mut self, v: ::std::string::String) { + self.one_of_start_field_id = ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_start_field_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(_)) = self.one_of_start_field_id { + } else { + self.one_of_start_field_id = ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(::std::string::String::new())); + } + match self.one_of_start_field_id { + ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_start_field_id(&mut self) -> ::std::string::String { + if self.has_start_field_id() { + match self.one_of_start_field_id.take() { + ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for CreateFieldPayload { + fn is_initialized(&self) -> bool { + for v in &self.field { + 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)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.type_option_data)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_start_field_id = ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if let Some(ref v) = self.field.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.type_option_data.is_empty() { + my_size += ::protobuf::rt::bytes_size(3, &self.type_option_data); + } + if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id { + match v { + &CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => { + my_size += ::protobuf::rt::string_size(4, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.field.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 !self.type_option_data.is_empty() { + os.write_bytes(3, &self.type_option_data)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id { + match v { + &CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => { + os.write_string(4, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CreateFieldPayload { + CreateFieldPayload::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: &CreateFieldPayload| { &m.grid_id }, + |m: &mut CreateFieldPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field", + |m: &CreateFieldPayload| { &m.field }, + |m: &mut CreateFieldPayload| { &mut m.field }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "type_option_data", + |m: &CreateFieldPayload| { &m.type_option_data }, + |m: &mut CreateFieldPayload| { &mut m.type_option_data }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "start_field_id", + CreateFieldPayload::has_start_field_id, + CreateFieldPayload::get_start_field_id, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateFieldPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateFieldPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateFieldPayload::new) + } +} + +impl ::protobuf::Clear for CreateFieldPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field.clear(); + self.type_option_data.clear(); + self.one_of_start_field_id = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateFieldPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateFieldPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct QueryFieldPayload { // message fields @@ -4101,14 +4441,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01\ (\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\ \x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstart\ - RowIdB\x15\n\x13one_of_start_row_id\"d\n\x11QueryFieldPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ - \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ - locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ - \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ - s\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ - ridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x15\n\x06\ - row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\ + RowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\ + \x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ + \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ + \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ + \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ + \x0f.GridBlockOrderR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ + \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ + b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 2e27686c00..df2c87d586 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -727,7 +727,7 @@ pub struct FieldMeta { pub frozen: bool, pub visibility: bool, pub width: i32, - pub type_options: ::std::string::String, + pub type_option: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -882,30 +882,30 @@ impl FieldMeta { self.width = v; } - // string type_options = 8; + // string type_option = 8; - pub fn get_type_options(&self) -> &str { - &self.type_options + pub fn get_type_option(&self) -> &str { + &self.type_option } - pub fn clear_type_options(&mut self) { - self.type_options.clear(); + pub fn clear_type_option(&mut self) { + self.type_option.clear(); } // Param is passed by value, moved - pub fn set_type_options(&mut self, v: ::std::string::String) { - self.type_options = v; + pub fn set_type_option(&mut self, v: ::std::string::String) { + self.type_option = 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 ::std::string::String { - &mut self.type_options + pub fn mut_type_option(&mut self) -> &mut ::std::string::String { + &mut self.type_option } // Take field - pub fn take_type_options(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_options, ::std::string::String::new()) + pub fn take_type_option(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_option, ::std::string::String::new()) } } @@ -952,7 +952,7 @@ impl ::protobuf::Message for FieldMeta { self.width = tmp; }, 8 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_options)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_option)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -987,8 +987,8 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } - if !self.type_options.is_empty() { - my_size += ::protobuf::rt::string_size(8, &self.type_options); + if !self.type_option.is_empty() { + my_size += ::protobuf::rt::string_size(8, &self.type_option); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1017,8 +1017,8 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { os.write_int32(7, self.width)?; } - if !self.type_options.is_empty() { - os.write_string(8, &self.type_options)?; + if !self.type_option.is_empty() { + os.write_string(8, &self.type_option)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1094,9 +1094,9 @@ impl ::protobuf::Message for FieldMeta { |m: &mut FieldMeta| { &mut m.width }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_options", - |m: &FieldMeta| { &m.type_options }, - |m: &mut FieldMeta| { &mut m.type_options }, + "type_option", + |m: &FieldMeta| { &m.type_option }, + |m: &mut FieldMeta| { &mut m.type_option }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldMeta", @@ -1121,7 +1121,7 @@ impl ::protobuf::Clear for FieldMeta { self.frozen = false; self.visibility = false; self.width = 0; - self.type_options.clear(); + self.type_option.clear(); self.unknown_fields.clear(); } } @@ -1142,6 +1142,7 @@ impl ::protobuf::reflect::ProtobufValue for FieldMeta { pub struct FieldChangeset { // message fields pub field_id: ::std::string::String, + pub grid_id: ::std::string::String, // message oneof groups pub one_of_name: ::std::option::Option, pub one_of_desc: ::std::option::Option, @@ -1227,7 +1228,33 @@ impl FieldChangeset { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string name = 2; + // 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()) + } + + // string name = 3; pub fn get_name(&self) -> &str { @@ -1276,7 +1303,7 @@ impl FieldChangeset { } } - // string desc = 3; + // string desc = 4; pub fn get_desc(&self) -> &str { @@ -1325,7 +1352,7 @@ impl FieldChangeset { } } - // .FieldType field_type = 4; + // .FieldType field_type = 5; pub fn get_field_type(&self) -> FieldType { @@ -1350,7 +1377,7 @@ impl FieldChangeset { self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) } - // bool frozen = 5; + // bool frozen = 6; pub fn get_frozen(&self) -> bool { @@ -1375,7 +1402,7 @@ impl FieldChangeset { self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) } - // bool visibility = 6; + // bool visibility = 7; pub fn get_visibility(&self) -> bool { @@ -1400,7 +1427,7 @@ impl FieldChangeset { self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) } - // int32 width = 7; + // int32 width = 8; pub fn get_width(&self) -> i32 { @@ -1425,7 +1452,7 @@ impl FieldChangeset { self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) } - // string type_options = 8; + // string type_options = 9; pub fn get_type_options(&self) -> &str { @@ -1488,42 +1515,45 @@ impl ::protobuf::Message for FieldChangeset { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, 2 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(is.read_string()?)); + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 3 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(is.read_string()?)); + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(is.read_string()?)); }, 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(is.read_enum()?)); + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(is.read_string()?)); }, 5 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(is.read_bool()?)); + self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(is.read_enum()?)); }, 6 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); + self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(is.read_bool()?)); }, 7 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(is.read_int32()?)); + self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); }, 8 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(is.read_int32()?)); + }, + 9 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -1544,24 +1574,27 @@ impl ::protobuf::Message for FieldChangeset { if !self.field_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.field_id); } + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_id); + } if let ::std::option::Option::Some(ref v) = self.one_of_name { match v { &FieldChangeset_oneof_one_of_name::name(ref v) => { - my_size += ::protobuf::rt::string_size(2, &v); + my_size += ::protobuf::rt::string_size(3, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_desc { match v { &FieldChangeset_oneof_one_of_desc::desc(ref v) => { - my_size += ::protobuf::rt::string_size(3, &v); + my_size += ::protobuf::rt::string_size(4, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_field_type { match v { &FieldChangeset_oneof_one_of_field_type::field_type(v) => { - my_size += ::protobuf::rt::enum_size(4, v); + my_size += ::protobuf::rt::enum_size(5, v); }, }; } @@ -1582,14 +1615,14 @@ impl ::protobuf::Message for FieldChangeset { if let ::std::option::Option::Some(ref v) = self.one_of_width { match v { &FieldChangeset_oneof_one_of_width::width(v) => { - my_size += ::protobuf::rt::value_size(7, v, ::protobuf::wire_format::WireTypeVarint); + my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_type_options { match v { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - my_size += ::protobuf::rt::string_size(8, &v); + my_size += ::protobuf::rt::string_size(9, &v); }, }; } @@ -1602,52 +1635,55 @@ impl ::protobuf::Message for FieldChangeset { if !self.field_id.is_empty() { os.write_string(1, &self.field_id)?; } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_id)?; + } if let ::std::option::Option::Some(ref v) = self.one_of_name { match v { &FieldChangeset_oneof_one_of_name::name(ref v) => { - os.write_string(2, v)?; + os.write_string(3, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_desc { match v { &FieldChangeset_oneof_one_of_desc::desc(ref v) => { - os.write_string(3, v)?; + os.write_string(4, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_field_type { match v { &FieldChangeset_oneof_one_of_field_type::field_type(v) => { - os.write_enum(4, ::protobuf::ProtobufEnum::value(&v))?; + os.write_enum(5, ::protobuf::ProtobufEnum::value(&v))?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_frozen { match v { &FieldChangeset_oneof_one_of_frozen::frozen(v) => { - os.write_bool(5, v)?; + os.write_bool(6, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_visibility { match v { &FieldChangeset_oneof_one_of_visibility::visibility(v) => { - os.write_bool(6, v)?; + os.write_bool(7, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_width { match v { &FieldChangeset_oneof_one_of_width::width(v) => { - os.write_int32(7, v)?; + os.write_int32(8, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_type_options { match v { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - os.write_string(8, v)?; + os.write_string(9, v)?; }, }; } @@ -1694,6 +1730,11 @@ impl ::protobuf::Message for FieldChangeset { |m: &FieldChangeset| { &m.field_id }, |m: &mut FieldChangeset| { &mut m.field_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &FieldChangeset| { &m.grid_id }, + |m: &mut FieldChangeset| { &mut m.grid_id }, + )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "name", FieldChangeset::has_name, @@ -1746,6 +1787,7 @@ impl ::protobuf::Message for FieldChangeset { impl ::protobuf::Clear for FieldChangeset { fn clear(&mut self) { self.field_id.clear(); + self.grid_id.clear(); self.one_of_name = ::std::option::Option::None; self.one_of_desc = ::std::option::Option::None; self.one_of_field_type = ::std::option::Option::None; @@ -3465,49 +3507,50 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\ aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\ - metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldM\ + metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdd\x01\n\tFieldM\ eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ - idth\x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\ + idth\x12\x1f\n\x0btype_option\x18\x08\x20\x01(\tR\ntypeOption\"\x96\x03\ \n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldI\ - d\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ - \x03\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ - .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\ - \x03R\x06frozen\x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibi\ - lity\x12\x16\n\x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12#\n\x0cty\ - pe_options\x18\x08\x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\ - \r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\ - \x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type\ - _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ - eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ - Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ - \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ - \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ - \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ - \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ - \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ - \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ - \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ - ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ - llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ - \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ - \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ - _of_visibility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\t\ - R\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\ - \x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ - \x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\ - \x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bf\ - ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bbloc\ - k_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fb\ - lock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaD\ - ata*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\ - \x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\ - \n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + d\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\ + \x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\ + \x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\ + \tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\ + \x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05w\ + idth\x18\x08\x20\x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\t\ + \x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_desc\ + B\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visi\ + bilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyD\ + ata\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05valu\ + e\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07\ + blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.Cel\ + lByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05\ + R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\ + \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ + \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\ + \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\ + \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\ + field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ + llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ + value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ + \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ + \x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChange\ + set\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_\ + id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\ + R\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bon\ + e_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\ + \x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bblock_metas\x18\x02\ + \x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fblock_meta_data\ + \x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaData*d\n\tField\ + Type\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08\ + DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSel\ + ect\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 00dee86f6b..b1252fc72e 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 @@ -67,6 +67,12 @@ message CreateRowPayload { string grid_id = 1; oneof one_of_start_row_id { string start_row_id = 2; }; } +message CreateFieldPayload { + string grid_id = 1; + Field field = 2; + bytes type_option_data = 3; + oneof one_of_start_field_id { string start_field_id = 4; }; +} message QueryFieldPayload { string grid_id = 1; RepeatedFieldOrder field_orders = 2; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 24e1d22696..10b1183fea 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -22,17 +22,18 @@ message FieldMeta { bool frozen = 5; bool visibility = 6; int32 width = 7; - string type_options = 8; + string type_option = 8; } message FieldChangeset { string field_id = 1; - oneof one_of_name { string name = 2; }; - oneof one_of_desc { string desc = 3; }; - oneof one_of_field_type { FieldType field_type = 4; }; - oneof one_of_frozen { bool frozen = 5; }; - oneof one_of_visibility { bool visibility = 6; }; - oneof one_of_width { int32 width = 7; }; - oneof one_of_type_options { string type_options = 8; }; + string grid_id = 2; + oneof one_of_name { string name = 3; }; + oneof one_of_desc { string desc = 4; }; + oneof one_of_field_type { FieldType field_type = 5; }; + oneof one_of_frozen { bool frozen = 6; }; + oneof one_of_visibility { bool visibility = 7; }; + oneof one_of_width { int32 width = 8; }; + oneof one_of_type_options { string type_options = 9; }; } message AnyData { string type_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 8d4ab37b6d..372433cd34 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -5,6 +5,7 @@ use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangeset, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, }; +use flowy_grid_data_model::parser::CreateFieldParams; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; @@ -35,15 +36,49 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { + pub fn create_field(&mut self, params: CreateFieldParams) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.fields.contains(&field_meta) { - tracing::warn!("Duplicate grid field"); - Ok(None) - } else { - grid.fields.push(field_meta); - Ok(Some(())) + let CreateFieldParams { + field, + type_option_data, + start_field_id, + .. + } = params; + + if grid + .fields + .iter() + .find(|field_meta| field_meta.id == field.id) + .is_some() + { + tracing::warn!("Create grid field"); + return Ok(None); } + + let type_option = + String::from_utf8(type_option_data).map_err(|e| CollaborateError::internal().context(e))?; + + let field_meta = FieldMeta { + id: field.id, + name: field.name, + desc: field.desc, + field_type: field.field_type, + frozen: field.frozen, + visibility: field.visibility, + width: field.width, + type_option, + }; + + let insert_index = match start_field_id { + None => None, + Some(start_field_id) => grid.fields.iter().position(|field| field.id == start_field_id), + }; + + match insert_index { + None => grid.fields.push(field_meta), + Some(index) => grid.fields.insert(index, field_meta), + } + Ok(Some(())) }) } @@ -130,7 +165,7 @@ impl GridMetaPad { } if let Some(type_options) = changeset.type_options { - field.type_options = type_options; + field.type_option = type_options; is_changed = Some(()) } From 3fdf922f81585f1372b5ddb5b541d91ea14adfb2 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 24 Mar 2022 17:09:05 +0800 Subject: [PATCH 058/179] chore: config create field pannel --- .../assets/images/grid/field/checkbox.svg | 4 + .../assets/images/grid/field/checklist.svg | 4 + .../assets/images/grid/field/date.svg | 6 + .../assets/images/grid/field/multi_select.svg | 8 + .../assets/images/grid/field/number.svg | 3 + .../images/grid/field/single_select.svg | 4 + .../assets/images/grid/field/text.svg | 4 + .../app_flowy/assets/images/grid/more.svg | 3 + .../app_flowy/assets/translations/en.json | 8 +- .../lib/startup/home_deps_resolver.dart | 18 +- .../lib/workspace/application/grid/data.dart | 5 +- .../grid/field/create_field_bloc.dart | 47 ++ .../grid/field/edit_field_bloc.dart | 54 +++ .../grid/field/field_edit_bloc.dart | 58 --- .../application/grid/field/field_service.dart | 100 +++- .../grid/field/grid_header_bloc.dart | 4 +- .../application/grid/grid_listenr.dart | 4 +- .../workspace/application/grid/prelude.dart | 3 +- .../widgets/header/create_field_pannel.dart | 88 ++++ .../grid/src/widgets/header/field_editor.dart | 213 ++------ .../src/widgets/header/field_name_input.dart | 32 ++ .../widgets/header/field_operation_list.dart | 100 ++++ .../widgets/header/field_tyep_switcher.dart | 37 ++ .../src/widgets/header/field_type_list.dart | 132 +++++ .../grid/src/widgets/header/header.dart | 28 +- .../grid/src/widgets/header/header_cell.dart | 13 +- .../lib/style_widget/button.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../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/checkbox_description.pb.dart | 58 --- .../checkbox_description.pbjson.dart | 20 - .../checkbox_description.pbserver.dart | 9 - .../flowy-grid/date_description.pb.dart | 76 --- .../flowy-grid/date_description.pbenum.dart | 45 -- .../flowy-grid/date_description.pbjson.dart | 45 -- .../flowy-grid/date_description.pbserver.dart | 9 - .../protobuf/flowy-grid/event_map.pbenum.dart | 2 + .../protobuf/flowy-grid/event_map.pbjson.dart | 3 +- .../flowy-grid/number_description.pb.dart | 118 ----- .../flowy-grid/number_description.pbenum.dart | 30 -- .../flowy-grid/number_description.pbjson.dart | 37 -- .../number_description.pbserver.dart | 9 - .../lib/protobuf/flowy-grid/protobuf.dart | 2 +- .../flowy-grid/selection_description.pb.dart | 196 -------- .../selection_description.pbenum.dart | 7 - .../selection_description.pbjson.dart | 44 -- .../selection_description.pbserver.dart | 9 - .../flowy-grid/text_type_option.pb.dart | 58 +++ ...enum.dart => text_type_option.pbenum.dart} | 2 +- .../flowy-grid/text_type_option.pbjson.dart | 20 + ...er.dart => text_type_option.pbserver.dart} | 4 +- .../protobuf/flowy-grid/type_options.pb.dart | 458 ------------------ .../flowy-grid/type_options.pbenum.dart | 62 --- .../flowy-grid/type_options.pbjson.dart | 125 ----- .../flowy-grid/type_options.pbserver.dart | 9 - frontend/app_flowy/pubspec.yaml | 1 + .../rust-lib/flowy-grid/src/event_handler.rs | 11 + frontend/rust-lib/flowy-grid/src/event_map.rs | 4 + .../src/protobuf/model/event_map.rs | 11 +- .../flowy-grid/src/protobuf/model/mod.rs | 6 +- ...ext_description.rs => text_type_option.rs} | 4 +- .../src/protobuf/proto/event_map.proto | 1 + ...scription.proto => text_type_option.proto} | 0 .../src/services/field/field_builder.rs | 48 +- .../type_options/checkbox_type_option.rs | 8 +- .../field/type_options/date_type_option.rs | 8 +- .../src/services/field/type_options/mod.rs | 4 +- .../field/type_options/number_type_option.rs | 6 +- .../type_options/selection_type_option.rs | 16 +- ...ext_description.rs => text_type_option.rs} | 4 +- .../flowy-grid/src/services/grid_editor.rs | 35 +- frontend/rust-lib/flowy-grid/src/util.rs | 11 +- .../flowy-grid/tests/grid/grid_test.rs | 8 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 50 +- .../src/parser/grid_params.rs | 4 - .../src/client_grid/grid_meta_pad.rs | 4 +- 78 files changed, 964 insertions(+), 2381 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/field/checkbox.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/checklist.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/date.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/multi_select.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/number.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/single_select.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/text.svg create mode 100644 frontend/app_flowy/assets/images/grid/more.svg create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pb.dart rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/{checkbox_description.pbenum.dart => text_type_option.pbenum.dart} (87%) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbjson.dart rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/{cell_data.pbserver.dart => text_type_option.pbserver.dart} (81%) delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart rename frontend/rust-lib/flowy-grid/src/protobuf/model/{text_description.rs => text_type_option.rs} (98%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{text_description.proto => text_type_option.proto} (100%) rename frontend/rust-lib/flowy-grid/src/services/field/type_options/{text_description.rs => text_type_option.rs} (90%) diff --git a/frontend/app_flowy/assets/images/grid/field/checkbox.svg b/frontend/app_flowy/assets/images/grid/field/checkbox.svg new file mode 100644 index 0000000000..37f52c47ed --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/checkbox.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/field/checklist.svg b/frontend/app_flowy/assets/images/grid/field/checklist.svg new file mode 100644 index 0000000000..3a88d236a1 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/checklist.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/field/date.svg b/frontend/app_flowy/assets/images/grid/field/date.svg new file mode 100644 index 0000000000..78243f1e75 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/date.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/app_flowy/assets/images/grid/field/multi_select.svg b/frontend/app_flowy/assets/images/grid/field/multi_select.svg new file mode 100644 index 0000000000..97a2e9c434 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/multi_select.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/app_flowy/assets/images/grid/field/number.svg b/frontend/app_flowy/assets/images/grid/field/number.svg new file mode 100644 index 0000000000..9d8b98d10d --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/number.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/assets/images/grid/field/single_select.svg b/frontend/app_flowy/assets/images/grid/field/single_select.svg new file mode 100644 index 0000000000..8ccbc9a2e3 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/single_select.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/field/text.svg b/frontend/app_flowy/assets/images/grid/field/text.svg new file mode 100644 index 0000000000..7befa5080f --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/more.svg b/frontend/app_flowy/assets/images/grid/more.svg new file mode 100644 index 0000000000..b191e64a10 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/more.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 27574db94e..5646cdff58 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -148,7 +148,13 @@ "insertLeft": "Insert Left", "insertRight": "Insert Right", "duplicate": "Duplicate", - "delete": "Delete" + "delete": "Delete", + "textFieldName": "Text", + "checkboxFieldName": "Number", + "dateFieldName": "Date", + "numberFieldName": "Number", + "singleSelectFieldName": "Select", + "multiSelectFieldName": "Multiselect" } } } diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 5c4fc6267f..1702544a64 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -103,15 +103,21 @@ class HomeDepsResolver { getIt.registerFactoryParam>( (gridId, fields) => GridHeaderBloc( - data: GridColumnData(fields: fields), - service: FieldService(), + data: GridHeaderData(gridId: gridId, fields: fields), + service: FieldService(gridId: gridId), ), ); - getIt.registerFactoryParam( - (field, _) => FieldEditBloc( - field: field, - service: FieldService(), + getIt.registerFactoryParam( + (data, _) => EditFieldBloc( + field: data.field, + service: FieldService(gridId: data.gridId), + ), + ); + + getIt.registerFactoryParam( + (gridId, _) => CreateFieldBloc( + service: FieldService(gridId: gridId), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index ff1b1e3efc..7c508a6867 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,7 +1,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -class GridColumnData { +class GridHeaderData { + final String gridId; final List fields; - GridColumnData({required this.fields}); + GridHeaderData({required this.gridId, required this.fields}); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart new file mode 100644 index 0000000000..0d9126cd1e --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart @@ -0,0 +1,47 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; +import 'package:dartz/dartz.dart'; + +part 'create_field_bloc.freezed.dart'; + +class CreateFieldBloc extends Bloc { + final FieldService service; + + CreateFieldBloc({required this.service}) : super(CreateFieldState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) {}, + updateName: (_UpdateName value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class CreateFieldEvent with _$CreateFieldEvent { + const factory CreateFieldEvent.initial() = _InitialField; + const factory CreateFieldEvent.updateName(String newName) = _UpdateName; +} + +@freezed +class CreateFieldState with _$CreateFieldState { + const factory CreateFieldState({ + required String errorText, + required Option field, + }) = _CreateFieldState; + + factory CreateFieldState.initial() => CreateFieldState( + field: none(), + errorText: '', + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart new file mode 100644 index 0000000000..0944bdd1bb --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart @@ -0,0 +1,54 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'edit_field_bloc.freezed.dart'; + +class EditFieldBloc extends Bloc { + final FieldService service; + + EditFieldBloc({required Field field, required this.service}) : super(EditFieldState.initial(field)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) {}, + updateFieldName: (_UpdateFieldName value) { + // + }, + hideField: (_HideField value) {}, + deleteField: (_DeleteField value) {}, + duplicateField: (_DuplicateField value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class EditFieldEvent with _$EditFieldEvent { + const factory EditFieldEvent.initial() = _InitialField; + const factory EditFieldEvent.updateFieldName(String name) = _UpdateFieldName; + const factory EditFieldEvent.hideField() = _HideField; + const factory EditFieldEvent.duplicateField() = _DuplicateField; + const factory EditFieldEvent.deleteField() = _DeleteField; +} + +@freezed +class EditFieldState with _$EditFieldState { + const factory EditFieldState({ + required Field field, + required String errorText, + }) = _EditFieldState; + + factory EditFieldState.initial(Field field) => EditFieldState( + field: field, + errorText: '', + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart deleted file mode 100644 index 2d4aea16da..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'field_service.dart'; - -part 'field_edit_bloc.freezed.dart'; - -class FieldEditBloc extends Bloc { - final FieldService service; - - FieldEditBloc({required Field field, required this.service}) : super(FieldEditState.initial(field)) { - on( - (event, emit) async { - await event.map( - initial: (_InitialField value) {}, - createField: (_CreateField value) {}, - updateFieldName: (_UpdateFieldName value) { - // - }, - hideField: (_HideField value) {}, - deleteField: (_DeleteField value) {}, - insertField: (_InsertField value) {}, - duplicateField: (_DuplicateField value) {}, - ); - }, - ); - } - - @override - Future close() async { - return super.close(); - } -} - -@freezed -class FieldEditEvent with _$FieldEditEvent { - const factory FieldEditEvent.initial() = _InitialField; - const factory FieldEditEvent.createField() = _CreateField; - const factory FieldEditEvent.updateFieldName(String name) = _UpdateFieldName; - const factory FieldEditEvent.hideField() = _HideField; - const factory FieldEditEvent.duplicateField() = _DuplicateField; - const factory FieldEditEvent.insertField({required bool onLeft}) = _InsertField; - const factory FieldEditEvent.deleteField() = _DeleteField; -} - -@freezed -class FieldEditState with _$FieldEditState { - const factory FieldEditState({ - required Field field, - required String errorText, - }) = _FieldEditState; - - factory FieldEditState.initial(Field field) => FieldEditState( - field: field, - errorText: '', - ); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 48d4aa21bd..5a8032b79a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -1 +1,99 @@ -class FieldService {} +import 'dart:typed_data'; + +import 'package:dartz/dartz.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart'; + +class FieldService { + final String gridId; + + FieldService({required this.gridId}); + + Future> getDefaultField( + String gridId, + ) { + final payload = GridId.create()..value = gridId; + return GridEventCreateDefaultField(payload).send(); + } + + Future> createTextField( + String gridId, + Field field, + RichTextTypeOption typeOption, + String? startFieldId, + ) { + final typeOptionData = typeOption.writeToBuffer(); + return _createField(gridId, field, typeOptionData, startFieldId); + } + + Future> createSingleSelectField( + String gridId, + Field field, + SingleSelectTypeOption typeOption, + String? startFieldId, + ) { + final typeOptionData = typeOption.writeToBuffer(); + return _createField(gridId, field, typeOptionData, startFieldId); + } + + Future> createMultiSelectField( + String gridId, + Field field, + MultiSelectTypeOption typeOption, + String? startFieldId, + ) { + final typeOptionData = typeOption.writeToBuffer(); + return _createField(gridId, field, typeOptionData, startFieldId); + } + + Future> createNumberField( + String gridId, + Field field, + NumberTypeOption typeOption, + String? startFieldId, + ) { + final typeOptionData = typeOption.writeToBuffer(); + return _createField(gridId, field, typeOptionData, startFieldId); + } + + Future> createDateField( + String gridId, + Field field, + DateTypeOption typeOption, + String? startFieldId, + ) { + final typeOptionData = typeOption.writeToBuffer(); + return _createField(gridId, field, typeOptionData, startFieldId); + } + + Future> _createField( + String gridId, + Field field, + Uint8List typeOptionData, + String? startFieldId, + ) { + final payload = CreateFieldPayload.create() + ..gridId = gridId + ..field_2 = field + ..typeOptionData = typeOptionData + ..startFieldId = startFieldId ?? ""; + + return GridEventCreateField(payload).send(); + } +} + +class GridFieldData extends Equatable { + final String gridId; + final Field field; + + const GridFieldData({ + required this.gridId, + required this.field, + }); + + @override + List get props => [field.id]; +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart index f4c7459337..a5f3a8414a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -11,7 +11,7 @@ class GridHeaderBloc extends Bloc { final FieldService service; GridHeaderBloc({ - required GridColumnData data, + required GridHeaderData data, required this.service, }) : super(GridHeaderState.initial(data.fields)) { on( @@ -19,6 +19,7 @@ class GridHeaderBloc extends Bloc { await event.map( initial: (_InitialHeader value) async {}, createField: (_CreateField value) {}, + insertField: (_InsertField value) {}, ); }, ); @@ -34,6 +35,7 @@ class GridHeaderBloc extends Bloc { class GridHeaderEvent with _$GridHeaderEvent { const factory GridHeaderEvent.initial() = _InitialHeader; const factory GridHeaderEvent.createField() = _CreateField; + const factory GridHeaderEvent.insertField({required bool onLeft}) = _InsertField; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart index e0423d7757..e110491912 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart @@ -31,9 +31,9 @@ class GridListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.DidUpdateRow: + case GridNotification.DidUpdateFields: result.fold( - (payload) => fieldsUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), + (payload) => fieldsUpdateNotifier.value = left(RepeatedField.fromBuffer(payload).items), (error) => fieldsUpdateNotifier.value = right(error), ); break; diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 3190ced75d..a1c60d7efb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -5,7 +5,8 @@ export 'grid_service.dart'; export 'data.dart'; export 'field/field_service.dart'; export 'field/grid_header_bloc.dart'; -export 'field/field_edit_bloc.dart'; +export 'field/edit_field_bloc.dart'; +export 'field/create_field_bloc.dart'; export 'cell_bloc/text_cell_bloc.dart'; export 'cell_bloc/number_cell_bloc.dart'; export 'cell_bloc/selection_cell_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart new file mode 100644 index 0000000000..69d57782a8 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -0,0 +1,88 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/create_field_bloc.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'field_name_input.dart'; +import 'field_tyep_switcher.dart'; + +class CreateFieldPannel extends StatelessWidget { + const CreateFieldPannel({Key? key}) : super(key: key); + + static void show(BuildContext context) { + const pannel = CreateFieldPannel(); + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: pannel, + constraints: BoxConstraints.loose(const Size(300, 200)), + ), + identifier: pannel.identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomWithLeftAligned, + style: FlowyOverlayStyle(blur: false), + ); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt()..add(const CreateFieldEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + return state.field.fold( + () => const SizedBox(), + (field) => Column(children: [ + const FlowyText.medium("Edit property"), + const VSpace(10), + _FieldNameTextField(field), + const VSpace(10), + _FieldTypeSwitcher(field), + ]), + ); + }, + ), + ); + } + + String identifier() { + return toString(); + } +} + +class _FieldTypeSwitcher extends StatelessWidget { + final Field field; + const _FieldTypeSwitcher(this.field, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return FieldTypeSwitcher( + field: field, + onSelectField: _switchToFieldType, + ); + } + + void _switchToFieldType(FieldType fieldType) { + throw UnimplementedError(); + } +} + +class _FieldNameTextField extends StatelessWidget { + final Field field; + const _FieldNameTextField(this.field, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return FieldNameTextField( + name: field.name, + errorText: context.read().state.errorText, + onNameChanged: (newName) { + context.read().add(CreateFieldEvent.updateName(newName)); + }, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index 531d83a1f3..c199553cc6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -1,52 +1,47 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:app_flowy/generated/locale_keys.g.dart'; + +import 'field_name_input.dart'; +import 'field_operation_list.dart'; +import 'field_tyep_switcher.dart'; class FieldEditor extends StatelessWidget { - final Field field; - const FieldEditor({required this.field, Key? key}) : super(key: key); + final GridFieldData fieldData; + const FieldEditor({required this.fieldData, Key? key}) : super(key: key); - static void show(BuildContext context, Field field) { - final editor = FieldEditor(field: field); + static void show(BuildContext context, GridFieldData fieldData) { + final editor = FieldEditor(fieldData: fieldData); FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer(child: editor), + widget: OverlayContainer( + child: editor, + constraints: BoxConstraints.loose(const Size(300, 200)), + ), identifier: editor.identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomWithLeftAligned, - style: FlowyOverlayStyle(blur: false), ); } @override Widget build(BuildContext context) { - final theme = context.watch(); return BlocProvider( - create: (context) => getIt(param1: field)..add(const FieldEditEvent.initial()), - child: Container( - color: theme.surface, - constraints: BoxConstraints.loose(const Size(300, 200)), - child: SingleChildScrollView( - child: Column(children: [ - const FieldNameTextField(), - // FieldTypeSwitcher(), - const VSpace(10), + create: (context) => getIt(param1: fieldData)..add(const EditFieldEvent.initial()), + child: SingleChildScrollView( + child: Column( + children: [ + const _FieldNameTextField(), + const VSpace(6), + const _FieldTypeSwitcher(), + const VSpace(6), FieldOperationList( - onTap: () { - FlowyOverlay.of(context).remove(identifier()); - }, + onDismiss: () => FlowyOverlay.of(context).remove(identifier()), ), - ]), + ], ), ), ); @@ -57,152 +52,40 @@ class FieldEditor extends StatelessWidget { } } -class FieldNameTextField extends StatelessWidget { - const FieldNameTextField({Key? key}) : super(key: key); +class _FieldTypeSwitcher extends StatelessWidget { + const _FieldTypeSwitcher({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final theme = context.watch(); - return BlocBuilder( + return BlocBuilder( + builder: (context, state) { + final field = context.read().state.field; + return FieldTypeSwitcher(field: field, onSelectField: _switchToFieldType); + }, + ); + } + + void _switchToFieldType(FieldType fieldType) { + throw UnimplementedError(); + } +} + +class _FieldNameTextField extends StatelessWidget { + const _FieldNameTextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( buildWhen: ((previous, current) => previous.field.name == current.field.name), builder: (context, state) { - return RoundedInputField( - height: 36, - style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), - initialValue: state.field.name, - normalBorderColor: theme.shader4, - errorBorderColor: theme.red, - focusBorderColor: theme.main1, - cursorColor: theme.main1, + return FieldNameTextField( + name: state.field.name, errorText: state.errorText, - onChanged: (value) { - context.read().add(FieldEditEvent.updateFieldName(value)); + onNameChanged: (newName) { + context.read().add(EditFieldEvent.updateFieldName(newName)); }, ); }, ); } } - -class FieldTypeSwitcher extends StatelessWidget { - const FieldTypeSwitcher({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - - return FlowyButton( - text: FlowyText.medium(context.read().state.field.name, fontSize: 12), - hoverColor: theme.hover, - onTap: () {}, - leftIcon: svg("editor/details", color: theme.iconColor), - ); - } -} - -class FieldOperationList extends StatelessWidget { - final VoidCallback onTap; - const FieldOperationList({required this.onTap, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final children = FieldAction.values - .map((action) => FieldActionItem( - action: action, - onTap: onTap, - )) - .toList(); - return GridView( - // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html - shrinkWrap: true, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 4.0, - mainAxisSpacing: 8, - ), - children: children, - ); - } -} - -class FieldActionItem extends StatelessWidget { - final VoidCallback onTap; - final FieldAction action; - const FieldActionItem({required this.action, required this.onTap, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return FlowyButton( - text: FlowyText.medium(action.title(), fontSize: 12), - hoverColor: theme.hover, - onTap: () { - action.run(context); - onTap(); - }, - leftIcon: svg(action.iconName(), color: theme.iconColor), - ); - } -} - -enum FieldAction { - hide, - insertLeft, - duplicate, - insertRight, - delete, -} - -extension _FieldActionExtension on FieldAction { - String iconName() { - switch (this) { - case FieldAction.hide: - return 'grid/hide'; - case FieldAction.insertLeft: - return 'grid/left'; - case FieldAction.insertRight: - return 'grid/right'; - case FieldAction.duplicate: - return 'grid/duplicate'; - case FieldAction.delete: - return 'grid/delete'; - } - } - - String title() { - switch (this) { - case FieldAction.hide: - return LocaleKeys.grid_field_hide.tr(); - case FieldAction.insertLeft: - return LocaleKeys.grid_field_insertLeft.tr(); - case FieldAction.insertRight: - return LocaleKeys.grid_field_insertRight.tr(); - case FieldAction.duplicate: - return LocaleKeys.grid_field_duplicate.tr(); - case FieldAction.delete: - return LocaleKeys.grid_field_delete.tr(); - } - } - - void run(BuildContext context) { - final bloc = context.read(); - - switch (this) { - case FieldAction.hide: - bloc.add(const FieldEditEvent.hideField()); - break; - case FieldAction.insertLeft: - bloc.add(const FieldEditEvent.insertField(onLeft: true)); - break; - case FieldAction.insertRight: - bloc.add(const FieldEditEvent.insertField(onLeft: false)); - break; - case FieldAction.duplicate: - bloc.add(const FieldEditEvent.duplicateField()); - break; - case FieldAction.delete: - bloc.add(const FieldEditEvent.deleteField()); - break; - } - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart new file mode 100644 index 0000000000..49f0513099 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart @@ -0,0 +1,32 @@ +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class FieldNameTextField extends StatelessWidget { + final void Function(String) onNameChanged; + final String name; + final String errorText; + const FieldNameTextField({ + required this.name, + required this.errorText, + required this.onNameChanged, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return RoundedInputField( + height: 36, + style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), + initialValue: name, + normalBorderColor: theme.shader4, + errorBorderColor: theme.red, + focusBorderColor: theme.main1, + cursorColor: theme.main1, + errorText: errorText, + onChanged: onNameChanged, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart new file mode 100644 index 0000000000..f803bdee58 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart @@ -0,0 +1,100 @@ +import 'package:app_flowy/workspace/application/grid/field/edit_field_bloc.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class FieldOperationList extends StatelessWidget { + final VoidCallback onDismiss; + const FieldOperationList({required this.onDismiss, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final children = FieldAction.values + .map((action) => FieldActionItem( + action: action, + onTap: onDismiss, + )) + .toList(); + return GridView( + // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.0, + mainAxisSpacing: 8, + ), + children: children, + ); + } +} + +class FieldActionItem extends StatelessWidget { + final VoidCallback onTap; + final FieldAction action; + const FieldActionItem({required this.action, required this.onTap, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: FlowyText.medium(action.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + action.run(context); + onTap(); + }, + leftIcon: svg(action.iconName(), color: theme.iconColor), + ); + } +} + +enum FieldAction { + hide, + // insertLeft, + duplicate, + // insertRight, + delete, +} + +extension _FieldActionExtension on FieldAction { + String iconName() { + switch (this) { + case FieldAction.hide: + return 'grid/hide'; + case FieldAction.duplicate: + return 'grid/duplicate'; + case FieldAction.delete: + return 'grid/delete'; + } + } + + String title() { + switch (this) { + case FieldAction.hide: + return LocaleKeys.grid_field_hide.tr(); + case FieldAction.duplicate: + return LocaleKeys.grid_field_duplicate.tr(); + case FieldAction.delete: + return LocaleKeys.grid_field_delete.tr(); + } + } + + void run(BuildContext context) { + switch (this) { + case FieldAction.hide: + context.read().add(const EditFieldEvent.hideField()); + break; + case FieldAction.duplicate: + context.read().add(const EditFieldEvent.duplicateField()); + break; + case FieldAction.delete: + context.read().add(const EditFieldEvent.deleteField()); + break; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart new file mode 100644 index 0000000000..505715d541 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -0,0 +1,37 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +typedef SelectFieldCallback = void Function(FieldType); + +class FieldTypeSwitcher extends StatelessWidget { + final Field field; + final SelectFieldCallback onSelectField; + const FieldTypeSwitcher({ + required this.field, + required this.onSelectField, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return SizedBox( + height: 36, + child: FlowyButton( + text: FlowyText.medium(field.name, fontSize: 12), + hoverColor: theme.hover, + onTap: () => FieldTypeList.show(context, onSelectField), + leftIcon: svg(field.fieldType.iconName(), color: theme.iconColor), + rightIcon: svg("grid/more", color: theme.iconColor), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart new file mode 100644 index 0000000000..aa5d22804d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -0,0 +1,132 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +typedef SelectFieldCallback = void Function(FieldType); + +class FieldTypeList extends StatelessWidget { + final SelectFieldCallback onSelectField; + const FieldTypeList({required this.onSelectField, Key? key}) : super(key: key); + + static void show(BuildContext context, SelectFieldCallback onSelectField) { + final list = FieldTypeList(onSelectField: onSelectField); + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: list, + constraints: BoxConstraints.loose(const Size(140, 300)), + ), + identifier: list.identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.leftWithCenterAligned, + style: FlowyOverlayStyle(blur: false), + anchorOffset: const Offset(-20, 0), + ); + } + + @override + Widget build(BuildContext context) { + final cells = FieldType.values.map((fieldType) { + return FieldTypeCell( + fieldType: fieldType, + onSelectField: (fieldType) { + onSelectField(fieldType); + FlowyOverlay.of(context).remove(identifier()); + }, + ); + }).toList(); + + return ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + itemCount: cells.length, + separatorBuilder: (context, index) { + return const VSpace(10); + }, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + ); + } + + String identifier() { + return toString(); + } +} + +class FieldTypeCell extends StatelessWidget { + final FieldType fieldType; + final SelectFieldCallback onSelectField; + const FieldTypeCell({ + required this.fieldType, + required this.onSelectField, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return SizedBox( + height: 26, + child: FlowyButton( + text: FlowyText.medium(fieldType.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () => onSelectField(fieldType), + leftIcon: svg(fieldType.iconName(), color: theme.iconColor), + ), + ); + } +} + +extension FieldTypeListExtension on FieldType { + String iconName() { + switch (this) { + case FieldType.Checkbox: + return "grid/field/checkbox"; + case FieldType.DateTime: + return "grid/field/date"; + case FieldType.MultiSelect: + return "grid/field/multi_select"; + case FieldType.Number: + return "grid/field/number"; + case FieldType.RichText: + return "grid/field/text"; + case FieldType.SingleSelect: + return "grid/field/single_select"; + default: + assert(false, "Unsupport field type"); + return "grid/field/text"; + } + } + + String title() { + switch (this) { + case FieldType.Checkbox: + return LocaleKeys.grid_field_checkboxFieldName.tr(); + case FieldType.DateTime: + return LocaleKeys.grid_field_dateFieldName.tr(); + case FieldType.MultiSelect: + return LocaleKeys.grid_field_multiSelectFieldName.tr(); + case FieldType.Number: + return LocaleKeys.grid_field_numberFieldName.tr(); + case FieldType.RichText: + return LocaleKeys.grid_field_textFieldName.tr(); + case FieldType.SingleSelect: + return LocaleKeys.grid_field_singleSelectFieldName.tr(); + default: + assert(false, "Unsupport field type"); + return LocaleKeys.grid_field_textFieldName.tr(); + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index f465e43843..1b1cde2acb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'create_field_pannel.dart'; import 'header_cell.dart'; class GridHeaderDelegate extends SliverPersistentHeaderDelegate { @@ -46,19 +47,30 @@ class GridHeader extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return BlocProvider( - create: (context) => getIt(param1: gridId, param2: fields)..add(const GridHeaderEvent.initial()), + create: (context) { + final bloc = getIt(param1: gridId, param2: fields); + bloc.add(const GridHeaderEvent.initial()); + return bloc; + }, child: BlocBuilder( - builder: (context, state) => Container( - color: theme.surface, - child: Row( + builder: (context, state) { + final cells = state.fields.map( + (field) => HeaderCell( + GridFieldData(gridId: gridId, field: field), + ), + ); + + final row = Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const _HeaderLeading(), - ...state.fields.map((field) => HeaderCell(field)), + ...cells, const _HeaderTrailing(), ], - ), - ), + ); + + return Container(color: theme.surface, child: row); + }, ), ); } @@ -102,7 +114,7 @@ class CreateFieldButton extends StatelessWidget { return FlowyButton( text: const FlowyText.medium('New column', fontSize: 12), hoverColor: theme.hover, - onTap: () => context.read().add(const GridHeaderEvent.createField()), + onTap: () => CreateFieldPannel.show(context), leftIcon: svg("home/add"), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 472c32d8f5..d6e0faff47 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,34 +1,33 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; - import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_editor.dart'; class HeaderCell extends StatelessWidget { - final Field field; - const HeaderCell(this.field, {Key? key}) : super(key: key); + final GridFieldData fieldData; + const HeaderCell(this.fieldData, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); final button = FlowyButton( hoverColor: theme.hover, - onTap: () => FieldEditor.show(context, field), + onTap: () => FieldEditor.show(context, fieldData), rightIcon: svg("editor/details", color: theme.iconColor), - text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(field.name, fontSize: 12)), + text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), ); final borderSide = BorderSide(color: theme.shader4, width: 0.4); final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); return Container( - width: field.width.toDouble(), + width: fieldData.field.width.toDouble(), decoration: decoration, padding: GridSize.headerContentInsets, child: button, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index dee66a8f11..d74edefba4 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -26,7 +26,7 @@ class FlowyButton extends StatelessWidget { return InkWell( onTap: onTap, child: FlowyHover( - config: HoverDisplayConfig(borderRadius: Corners.s5Border, hoverColor: hoverColor), + config: HoverDisplayConfig(borderRadius: Corners.s6Border, hoverColor: hoverColor), builder: (context, onHover) => _render(), ), ); 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 80b965177c..c5f7002138 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 @@ -86,6 +86,23 @@ class GridEventCreateField { } } +class GridEventCreateDefaultField { + GridId request; + GridEventCreateDefaultField(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.CreateDefaultField.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Field.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateRow { CreateRowPayload request; GridEventCreateRow(this.request); 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 deleted file mode 100644 index d87c9e02c7..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pb.dart +++ /dev/null @@ -1,458 +0,0 @@ -/// -// 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 deleted file mode 100644 index b6512aafba..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbenum.dart +++ /dev/null @@ -1,62 +0,0 @@ -/// -// 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 deleted file mode 100644 index c2caf59394..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbjson.dart +++ /dev/null @@ -1,125 +0,0 @@ -/// -// 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/checkbox_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart deleted file mode 100644 index 04b2ae6e81..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart +++ /dev/null @@ -1,58 +0,0 @@ -/// -// Generated code. Do not modify. -// source: checkbox_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -class CheckboxTypeOption extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxTypeOption', createEmptyInstance: create) - ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') - ..hasRequiredFields = false - ; - - CheckboxTypeOption._() : super(); - factory CheckboxTypeOption({ - $core.bool? isSelected, - }) { - final _result = create(); - if (isSelected != null) { - _result.isSelected = isSelected; - } - return _result; - } - factory CheckboxTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CheckboxTypeOption.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') - CheckboxTypeOption clone() => CheckboxTypeOption()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CheckboxTypeOption copyWith(void Function(CheckboxTypeOption) updates) => super.copyWith((message) => updates(message as CheckboxTypeOption)) as CheckboxTypeOption; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CheckboxTypeOption create() => CheckboxTypeOption._(); - CheckboxTypeOption createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CheckboxTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CheckboxTypeOption? _defaultInstance; - - @$pb.TagNumber(1) - $core.bool get isSelected => $_getBF(0); - @$pb.TagNumber(1) - set isSelected($core.bool v) { $_setBool(0, v); } - @$pb.TagNumber(1) - $core.bool hasIsSelected() => $_has(0); - @$pb.TagNumber(1) - void clearIsSelected() => clearField(1); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart deleted file mode 100644 index 0569b0665a..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// -// Generated code. Do not modify. -// source: checkbox_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use checkboxTypeOptionDescriptor instead') -const CheckboxTypeOption$json = const { - '1': 'CheckboxTypeOption', - '2': const [ - const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, - ], -}; - -/// Descriptor for `CheckboxTypeOption`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List checkboxTypeOptionDescriptor = $convert.base64Decode('ChJDaGVja2JveFR5cGVPcHRpb24SHwoLaXNfc2VsZWN0ZWQYASABKAhSCmlzU2VsZWN0ZWQ='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart deleted file mode 100644 index 166969b429..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: checkbox_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -export 'checkbox_description.pb.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart deleted file mode 100644 index a70bff6f3c..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart +++ /dev/null @@ -1,76 +0,0 @@ -/// -// Generated code. Do not modify. -// source: date_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'date_description.pbenum.dart'; - -export 'date_description.pbenum.dart'; - -class DateDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateDescription', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values) - ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values) - ..hasRequiredFields = false - ; - - DateDescription._() : super(); - factory DateDescription({ - DateFormat? dateFormat, - TimeFormat? timeFormat, - }) { - final _result = create(); - if (dateFormat != null) { - _result.dateFormat = dateFormat; - } - if (timeFormat != null) { - _result.timeFormat = timeFormat; - } - return _result; - } - factory DateDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory DateDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - DateDescription clone() => DateDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - DateDescription copyWith(void Function(DateDescription) updates) => super.copyWith((message) => updates(message as DateDescription)) as DateDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static DateDescription create() => DateDescription._(); - DateDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static DateDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static DateDescription? _defaultInstance; - - @$pb.TagNumber(1) - DateFormat get dateFormat => $_getN(0); - @$pb.TagNumber(1) - set dateFormat(DateFormat v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasDateFormat() => $_has(0); - @$pb.TagNumber(1) - void clearDateFormat() => clearField(1); - - @$pb.TagNumber(2) - TimeFormat get timeFormat => $_getN(1); - @$pb.TagNumber(2) - set timeFormat(TimeFormat v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasTimeFormat() => $_has(1); - @$pb.TagNumber(2) - void clearTimeFormat() => clearField(2); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart deleted file mode 100644 index 93ea01d9be..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart +++ /dev/null @@ -1,45 +0,0 @@ -/// -// Generated code. Do not modify. -// source: date_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class DateFormat extends $pb.ProtobufEnum { - static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); - static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); - static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); - static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); - - static const $core.List values = [ - Local, - US, - ISO, - Friendly, - ]; - - static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); - static DateFormat? valueOf($core.int value) => _byValue[value]; - - const DateFormat._($core.int v, $core.String n) : super(v, n); -} - -class TimeFormat extends $pb.ProtobufEnum { - static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); - static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); - - static const $core.List values = [ - TwelveHour, - TwentyFourHour, - ]; - - static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); - static TimeFormat? valueOf($core.int value) => _byValue[value]; - - const TimeFormat._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart deleted file mode 100644 index 841db39005..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart +++ /dev/null @@ -1,45 +0,0 @@ -/// -// Generated code. Do not modify. -// source: date_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use dateFormatDescriptor instead') -const DateFormat$json = const { - '1': 'DateFormat', - '2': const [ - const {'1': 'Local', '2': 0}, - const {'1': 'US', '2': 1}, - const {'1': 'ISO', '2': 2}, - const {'1': 'Friendly', '2': 3}, - ], -}; - -/// Descriptor for `DateFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List dateFormatDescriptor = $convert.base64Decode('CgpEYXRlRm9ybWF0EgkKBUxvY2FsEAASBgoCVVMQARIHCgNJU08QAhIMCghGcmllbmRseRAD'); -@$core.Deprecated('Use timeFormatDescriptor instead') -const TimeFormat$json = const { - '1': 'TimeFormat', - '2': const [ - const {'1': 'TwelveHour', '2': 0}, - const {'1': 'TwentyFourHour', '2': 1}, - ], -}; - -/// Descriptor for `TimeFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List timeFormatDescriptor = $convert.base64Decode('CgpUaW1lRm9ybWF0Eg4KClR3ZWx2ZUhvdXIQABISCg5Ud2VudHlGb3VySG91chAB'); -@$core.Deprecated('Use dateDescriptionDescriptor instead') -const DateDescription$json = const { - '1': 'DateDescription', - '2': const [ - const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'}, - const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'}, - ], -}; - -/// Descriptor for `DateDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List dateDescriptionDescriptor = $convert.base64Decode('Cg9EYXRlRGVzY3JpcHRpb24SLAoLZGF0ZV9mb3JtYXQYASABKA4yCy5EYXRlRm9ybWF0UgpkYXRlRm9ybWF0EiwKC3RpbWVfZm9ybWF0GAIgASgOMgsuVGltZUZvcm1hdFIKdGltZUZvcm1hdA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart deleted file mode 100644 index dd4ff2c3c7..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: date_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -export 'date_description.pb.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 4488ba1a3d..7007f1f6c8 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 @@ -15,6 +15,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); + static const GridEvent CreateDefaultField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultField'); static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); @@ -25,6 +26,7 @@ class GridEvent extends $pb.ProtobufEnum { GetFields, UpdateField, CreateField, + CreateDefaultField, CreateRow, GetRow, UpdateCell, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index c70007eaaa..1d94f8227a 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 @@ -17,6 +17,7 @@ const GridEvent$json = const { const {'1': 'GetFields', '2': 10}, const {'1': 'UpdateField', '2': 11}, const {'1': 'CreateField', '2': 12}, + const {'1': 'CreateDefaultField', '2': 13}, const {'1': 'CreateRow', '2': 21}, const {'1': 'GetRow', '2': 22}, const {'1': 'UpdateCell', '2': 30}, @@ -24,4 +25,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg0KCUNyZWF0ZVJvdxAVEgoKBkdldFJvdxAWEg4KClVwZGF0ZUNlbGwQHg=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEhYKEkNyZWF0ZURlZmF1bHRGaWVsZBANEg0KCUNyZWF0ZVJvdxAVEgoKBkdldFJvdxAWEg4KClVwZGF0ZUNlbGwQHg=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart deleted file mode 100644 index 19064fbfd1..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart +++ /dev/null @@ -1,118 +0,0 @@ -/// -// Generated code. Do not modify. -// source: number_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'number_description.pbenum.dart'; - -export 'number_description.pbenum.dart'; - -class NumberDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format', $pb.PbFieldType.OE, defaultOrMaker: NumberFormat.Number, valueOf: NumberFormat.valueOf, enumValues: NumberFormat.values) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') - ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..hasRequiredFields = false - ; - - NumberDescription._() : super(); - factory NumberDescription({ - NumberFormat? format, - $core.int? scale, - $core.String? symbol, - $core.bool? signPositive, - $core.String? name, - }) { - final _result = create(); - if (format != null) { - _result.format = format; - } - 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) - NumberFormat get format => $_getN(0); - @$pb.TagNumber(1) - set format(NumberFormat v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasFormat() => $_has(0); - @$pb.TagNumber(1) - void clearFormat() => clearField(1); - - @$pb.TagNumber(2) - $core.int get scale => $_getIZ(1); - @$pb.TagNumber(2) - set scale($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasScale() => $_has(1); - @$pb.TagNumber(2) - void clearScale() => clearField(2); - - @$pb.TagNumber(3) - $core.String get symbol => $_getSZ(2); - @$pb.TagNumber(3) - set symbol($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasSymbol() => $_has(2); - @$pb.TagNumber(3) - void clearSymbol() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get signPositive => $_getBF(3); - @$pb.TagNumber(4) - set signPositive($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasSignPositive() => $_has(3); - @$pb.TagNumber(4) - void clearSignPositive() => clearField(4); - - @$pb.TagNumber(5) - $core.String get name => $_getSZ(4); - @$pb.TagNumber(5) - set name($core.String v) { $_setString(4, v); } - @$pb.TagNumber(5) - $core.bool hasName() => $_has(4); - @$pb.TagNumber(5) - void clearName() => clearField(5); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart deleted file mode 100644 index f5c3d38628..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart +++ /dev/null @@ -1,30 +0,0 @@ -/// -// Generated code. Do not modify. -// source: number_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class NumberFormat extends $pb.ProtobufEnum { - static const NumberFormat Number = NumberFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); - static const NumberFormat USD = NumberFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); - static const NumberFormat CNY = NumberFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); - static const NumberFormat EUR = NumberFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - - static const $core.List values = [ - Number, - USD, - CNY, - EUR, - ]; - - static final $core.Map<$core.int, NumberFormat> _byValue = $pb.ProtobufEnum.initByValue(values); - static NumberFormat? valueOf($core.int value) => _byValue[value]; - - const NumberFormat._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart deleted file mode 100644 index ff1b3dc40f..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart +++ /dev/null @@ -1,37 +0,0 @@ -/// -// Generated code. Do not modify. -// source: number_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use numberFormatDescriptor instead') -const NumberFormat$json = const { - '1': 'NumberFormat', - '2': const [ - const {'1': 'Number', '2': 0}, - const {'1': 'USD', '2': 1}, - const {'1': 'CNY', '2': 2}, - const {'1': 'EUR', '2': 3}, - ], -}; - -/// Descriptor for `NumberFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List numberFormatDescriptor = $convert.base64Decode('CgxOdW1iZXJGb3JtYXQSCgoGTnVtYmVyEAASBwoDVVNEEAESBwoDQ05ZEAISBwoDRVVSEAM='); -@$core.Deprecated('Use numberDescriptionDescriptor instead') -const NumberDescription$json = const { - '1': 'NumberDescription', - '2': const [ - const {'1': 'format', '3': 1, '4': 1, '5': 14, '6': '.NumberFormat', '10': 'format'}, - const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, - const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, - const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, - 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('ChFOdW1iZXJEZXNjcmlwdGlvbhIlCgZmb3JtYXQYASABKA4yDS5OdW1iZXJGb3JtYXRSBmZvcm1hdBIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart deleted file mode 100644 index 58225a92b7..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: number_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -export 'number_description.pb.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index 8f0a7e7d48..874107f9be 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,8 +1,8 @@ // Auto-generated, do not edit export './number_type_option.pb.dart'; -export './text_description.pb.dart'; export './dart_notification.pb.dart'; export './selection_type_option.pb.dart'; export './checkbox_type_option.pb.dart'; export './event_map.pb.dart'; +export './text_type_option.pb.dart'; export './date_type_option.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart deleted file mode 100644 index 27b2fa8431..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart +++ /dev/null @@ -1,196 +0,0 @@ -/// -// Generated code. Do not modify. -// source: selection_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -class SingleSelectDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectDescription', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') - ..hasRequiredFields = false - ; - - SingleSelectDescription._() : super(); - factory SingleSelectDescription({ - $core.Iterable? options, - $core.bool? disableColor, - }) { - final _result = create(); - if (options != null) { - _result.options.addAll(options); - } - if (disableColor != null) { - _result.disableColor = disableColor; - } - return _result; - } - factory SingleSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory SingleSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SingleSelectDescription clone() => SingleSelectDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SingleSelectDescription copyWith(void Function(SingleSelectDescription) updates) => super.copyWith((message) => updates(message as SingleSelectDescription)) as SingleSelectDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static SingleSelectDescription create() => SingleSelectDescription._(); - SingleSelectDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SingleSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static SingleSelectDescription? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get options => $_getList(0); - - @$pb.TagNumber(2) - $core.bool get disableColor => $_getBF(1); - @$pb.TagNumber(2) - set disableColor($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasDisableColor() => $_has(1); - @$pb.TagNumber(2) - void clearDisableColor() => clearField(2); -} - -class MultiSelectDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectDescription', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') - ..hasRequiredFields = false - ; - - MultiSelectDescription._() : super(); - factory MultiSelectDescription({ - $core.Iterable? options, - $core.bool? disableColor, - }) { - final _result = create(); - if (options != null) { - _result.options.addAll(options); - } - if (disableColor != null) { - _result.disableColor = disableColor; - } - return _result; - } - factory MultiSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory MultiSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - MultiSelectDescription clone() => MultiSelectDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - MultiSelectDescription copyWith(void Function(MultiSelectDescription) updates) => super.copyWith((message) => updates(message as MultiSelectDescription)) as MultiSelectDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static MultiSelectDescription create() => MultiSelectDescription._(); - MultiSelectDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static MultiSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static MultiSelectDescription? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get options => $_getList(0); - - @$pb.TagNumber(2) - $core.bool get disableColor => $_getBF(1); - @$pb.TagNumber(2) - set disableColor($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasDisableColor() => $_has(1); - @$pb.TagNumber(2) - void clearDisableColor() => clearField(2); -} - -class SelectOption extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') - ..hasRequiredFields = false - ; - - SelectOption._() : super(); - factory SelectOption({ - $core.String? id, - $core.String? name, - $core.String? color, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (color != null) { - _result.color = color; - } - return _result; - } - factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SelectOption clone() => SelectOption()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static SelectOption create() => SelectOption._(); - SelectOption createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static SelectOption? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); - @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); - @$pb.TagNumber(2) - void clearName() => clearField(2); - - @$pb.TagNumber(3) - $core.String get color => $_getSZ(2); - @$pb.TagNumber(3) - set color($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasColor() => $_has(2); - @$pb.TagNumber(3) - void clearColor() => clearField(3); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart deleted file mode 100644 index 6688bc34c9..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart +++ /dev/null @@ -1,7 +0,0 @@ -/// -// Generated code. Do not modify. -// source: selection_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart deleted file mode 100644 index 6bb0c9e4db..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart +++ /dev/null @@ -1,44 +0,0 @@ -/// -// Generated code. Do not modify. -// source: selection_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use singleSelectDescriptionDescriptor instead') -const SingleSelectDescription$json = const { - '1': 'SingleSelectDescription', - '2': const [ - const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, - const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, - ], -}; - -/// Descriptor for `SingleSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List singleSelectDescriptionDescriptor = $convert.base64Decode('ChdTaW5nbGVTZWxlY3REZXNjcmlwdGlvbhInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); -@$core.Deprecated('Use multiSelectDescriptionDescriptor instead') -const MultiSelectDescription$json = const { - '1': 'MultiSelectDescription', - '2': const [ - const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, - const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, - ], -}; - -/// Descriptor for `MultiSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List multiSelectDescriptionDescriptor = $convert.base64Decode('ChZNdWx0aVNlbGVjdERlc2NyaXB0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); -@$core.Deprecated('Use selectOptionDescriptor instead') -const SelectOption$json = const { - '1': 'SelectOption', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, - ], -}; - -/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart deleted file mode 100644 index f55cbba1ec..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: selection_description.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -export 'selection_description.pb.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pb.dart new file mode 100644 index 0000000000..c30f2eb6e1 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pb.dart @@ -0,0 +1,58 @@ +/// +// Generated code. Do not modify. +// source: text_type_option.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class RichTextTypeOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextTypeOption', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') + ..hasRequiredFields = false + ; + + RichTextTypeOption._() : super(); + factory RichTextTypeOption({ + $core.String? format, + }) { + final _result = create(); + if (format != null) { + _result.format = format; + } + return _result; + } + factory RichTextTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RichTextTypeOption.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') + RichTextTypeOption clone() => RichTextTypeOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RichTextTypeOption copyWith(void Function(RichTextTypeOption) updates) => super.copyWith((message) => updates(message as RichTextTypeOption)) as RichTextTypeOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RichTextTypeOption create() => RichTextTypeOption._(); + RichTextTypeOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RichTextTypeOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RichTextTypeOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get format => $_getSZ(0); + @$pb.TagNumber(1) + set format($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFormat() => $_has(0); + @$pb.TagNumber(1) + void clearFormat() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbenum.dart similarity index 87% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbenum.dart index 0070b08607..f2bd90bfa5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbenum.dart @@ -1,6 +1,6 @@ /// // Generated code. Do not modify. -// source: checkbox_description.proto +// source: text_type_option.proto // // @dart = 2.12 // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbjson.dart new file mode 100644 index 0000000000..e4ba6956ee --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbjson.dart @@ -0,0 +1,20 @@ +/// +// Generated code. Do not modify. +// source: text_type_option.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 richTextTypeOptionDescriptor instead') +const RichTextTypeOption$json = const { + '1': 'RichTextTypeOption', + '2': const [ + const {'1': 'format', '3': 1, '4': 1, '5': 9, '10': 'format'}, + ], +}; + +/// Descriptor for `RichTextTypeOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List richTextTypeOptionDescriptor = $convert.base64Decode('ChJSaWNoVGV4dFR5cGVPcHRpb24SFgoGZm9ybWF0GAEgASgJUgZmb3JtYXQ='); 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/text_type_option.pbserver.dart similarity index 81% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_type_option.pbserver.dart index bae86fb5d9..6620aa1ee7 100644 --- 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/text_type_option.pbserver.dart @@ -1,9 +1,9 @@ /// // Generated code. Do not modify. -// source: cell_data.proto +// source: text_type_option.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'; +export 'text_type_option.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart deleted file mode 100644 index 152eef0c74..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart +++ /dev/null @@ -1,458 +0,0 @@ -/// -// Generated code. Do not modify. -// source: type_options.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'type_options.pbenum.dart'; - -export 'type_options.pbenum.dart'; - -class RichTextDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextDescription', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') - ..hasRequiredFields = false - ; - - RichTextDescription._() : super(); - factory RichTextDescription({ - $core.String? format, - }) { - final _result = create(); - if (format != null) { - _result.format = format; - } - return _result; - } - factory RichTextDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RichTextDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RichTextDescription clone() => RichTextDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RichTextDescription copyWith(void Function(RichTextDescription) updates) => super.copyWith((message) => updates(message as RichTextDescription)) as RichTextDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RichTextDescription create() => RichTextDescription._(); - RichTextDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RichTextDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RichTextDescription? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get format => $_getSZ(0); - @$pb.TagNumber(1) - set format($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasFormat() => $_has(0); - @$pb.TagNumber(1) - void clearFormat() => clearField(1); -} - -class CheckboxDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxDescription', createEmptyInstance: create) - ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') - ..hasRequiredFields = false - ; - - CheckboxDescription._() : super(); - factory CheckboxDescription({ - $core.bool? isSelected, - }) { - final _result = create(); - if (isSelected != null) { - _result.isSelected = isSelected; - } - return _result; - } - factory CheckboxDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CheckboxDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CheckboxDescription clone() => CheckboxDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CheckboxDescription copyWith(void Function(CheckboxDescription) updates) => super.copyWith((message) => updates(message as CheckboxDescription)) as CheckboxDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CheckboxDescription create() => CheckboxDescription._(); - CheckboxDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CheckboxDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CheckboxDescription? _defaultInstance; - - @$pb.TagNumber(1) - $core.bool get isSelected => $_getBF(0); - @$pb.TagNumber(1) - set isSelected($core.bool v) { $_setBool(0, v); } - @$pb.TagNumber(1) - $core.bool hasIsSelected() => $_has(0); - @$pb.TagNumber(1) - void clearIsSelected() => clearField(1); -} - -class DateDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateDescription', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values) - ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values) - ..hasRequiredFields = false - ; - - DateDescription._() : super(); - factory DateDescription({ - DateFormat? dateFormat, - TimeFormat? timeFormat, - }) { - final _result = create(); - if (dateFormat != null) { - _result.dateFormat = dateFormat; - } - if (timeFormat != null) { - _result.timeFormat = timeFormat; - } - return _result; - } - factory DateDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory DateDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - DateDescription clone() => DateDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - DateDescription copyWith(void Function(DateDescription) updates) => super.copyWith((message) => updates(message as DateDescription)) as DateDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static DateDescription create() => DateDescription._(); - DateDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static DateDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static DateDescription? _defaultInstance; - - @$pb.TagNumber(1) - DateFormat get dateFormat => $_getN(0); - @$pb.TagNumber(1) - set dateFormat(DateFormat v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasDateFormat() => $_has(0); - @$pb.TagNumber(1) - void clearDateFormat() => clearField(1); - - @$pb.TagNumber(2) - TimeFormat get timeFormat => $_getN(1); - @$pb.TagNumber(2) - set timeFormat(TimeFormat v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasTimeFormat() => $_has(1); - @$pb.TagNumber(2) - void clearTimeFormat() => clearField(2); -} - -class SingleSelectDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectDescription', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') - ..hasRequiredFields = false - ; - - SingleSelectDescription._() : super(); - factory SingleSelectDescription({ - $core.Iterable? options, - $core.bool? disableColor, - }) { - final _result = create(); - if (options != null) { - _result.options.addAll(options); - } - if (disableColor != null) { - _result.disableColor = disableColor; - } - return _result; - } - factory SingleSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory SingleSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SingleSelectDescription clone() => SingleSelectDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SingleSelectDescription copyWith(void Function(SingleSelectDescription) updates) => super.copyWith((message) => updates(message as SingleSelectDescription)) as SingleSelectDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static SingleSelectDescription create() => SingleSelectDescription._(); - SingleSelectDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SingleSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static SingleSelectDescription? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get options => $_getList(0); - - @$pb.TagNumber(2) - $core.bool get disableColor => $_getBF(1); - @$pb.TagNumber(2) - set disableColor($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasDisableColor() => $_has(1); - @$pb.TagNumber(2) - void clearDisableColor() => clearField(2); -} - -class MultiSelectDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectDescription', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') - ..hasRequiredFields = false - ; - - MultiSelectDescription._() : super(); - factory MultiSelectDescription({ - $core.Iterable? options, - $core.bool? disableColor, - }) { - final _result = create(); - if (options != null) { - _result.options.addAll(options); - } - if (disableColor != null) { - _result.disableColor = disableColor; - } - return _result; - } - factory MultiSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory MultiSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - MultiSelectDescription clone() => MultiSelectDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - MultiSelectDescription copyWith(void Function(MultiSelectDescription) updates) => super.copyWith((message) => updates(message as MultiSelectDescription)) as MultiSelectDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static MultiSelectDescription create() => MultiSelectDescription._(); - MultiSelectDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static MultiSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static MultiSelectDescription? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get options => $_getList(0); - - @$pb.TagNumber(2) - $core.bool get disableColor => $_getBF(1); - @$pb.TagNumber(2) - set disableColor($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasDisableColor() => $_has(1); - @$pb.TagNumber(2) - void clearDisableColor() => clearField(2); -} - -class SelectOption extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') - ..hasRequiredFields = false - ; - - SelectOption._() : super(); - factory SelectOption({ - $core.String? id, - $core.String? name, - $core.String? color, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (color != null) { - _result.color = color; - } - return _result; - } - factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SelectOption clone() => SelectOption()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static SelectOption create() => SelectOption._(); - SelectOption createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static SelectOption? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); - @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); - @$pb.TagNumber(2) - void clearName() => clearField(2); - - @$pb.TagNumber(3) - $core.String get color => $_getSZ(2); - @$pb.TagNumber(3) - set color($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasColor() => $_has(2); - @$pb.TagNumber(3) - void clearColor() => clearField(3); -} - -class NumberDescription extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') - ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..hasRequiredFields = false - ; - - NumberDescription._() : super(); - factory NumberDescription({ - MoneySymbol? money, - $core.int? scale, - $core.String? symbol, - $core.bool? signPositive, - $core.String? name, - }) { - final _result = create(); - if (money != null) { - _result.money = money; - } - if (scale != null) { - _result.scale = scale; - } - if (symbol != null) { - _result.symbol = symbol; - } - if (signPositive != null) { - _result.signPositive = signPositive; - } - if (name != null) { - _result.name = name; - } - return _result; - } - factory NumberDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory NumberDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - NumberDescription clone() => NumberDescription()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - NumberDescription copyWith(void Function(NumberDescription) updates) => super.copyWith((message) => updates(message as NumberDescription)) as NumberDescription; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static NumberDescription create() => NumberDescription._(); - NumberDescription createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static NumberDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static NumberDescription? _defaultInstance; - - @$pb.TagNumber(1) - MoneySymbol get money => $_getN(0); - @$pb.TagNumber(1) - set money(MoneySymbol v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasMoney() => $_has(0); - @$pb.TagNumber(1) - void clearMoney() => clearField(1); - - @$pb.TagNumber(2) - $core.int get scale => $_getIZ(1); - @$pb.TagNumber(2) - set scale($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasScale() => $_has(1); - @$pb.TagNumber(2) - void clearScale() => clearField(2); - - @$pb.TagNumber(3) - $core.String get symbol => $_getSZ(2); - @$pb.TagNumber(3) - set symbol($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasSymbol() => $_has(2); - @$pb.TagNumber(3) - void clearSymbol() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get signPositive => $_getBF(3); - @$pb.TagNumber(4) - set signPositive($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasSignPositive() => $_has(3); - @$pb.TagNumber(4) - void clearSignPositive() => clearField(4); - - @$pb.TagNumber(5) - $core.String get name => $_getSZ(4); - @$pb.TagNumber(5) - set name($core.String v) { $_setString(4, v); } - @$pb.TagNumber(5) - $core.bool hasName() => $_has(4); - @$pb.TagNumber(5) - void clearName() => clearField(5); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart deleted file mode 100644 index c3815cf5e1..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart +++ /dev/null @@ -1,62 +0,0 @@ -/// -// Generated code. Do not modify. -// source: type_options.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class DateFormat extends $pb.ProtobufEnum { - static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); - static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); - static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); - static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); - - static const $core.List values = [ - Local, - US, - ISO, - Friendly, - ]; - - static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); - static DateFormat? valueOf($core.int value) => _byValue[value]; - - const DateFormat._($core.int v, $core.String n) : super(v, n); -} - -class TimeFormat extends $pb.ProtobufEnum { - static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); - static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); - - static const $core.List values = [ - TwelveHour, - TwentyFourHour, - ]; - - static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); - static TimeFormat? valueOf($core.int value) => _byValue[value]; - - const TimeFormat._($core.int v, $core.String n) : super(v, n); -} - -class MoneySymbol extends $pb.ProtobufEnum { - static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); - static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); - - static const $core.List values = [ - CNY, - EUR, - USD, - ]; - - static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); - static MoneySymbol? valueOf($core.int value) => _byValue[value]; - - const MoneySymbol._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart deleted file mode 100644 index 71e0cf884b..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart +++ /dev/null @@ -1,125 +0,0 @@ -/// -// Generated code. Do not modify. -// source: type_options.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use dateFormatDescriptor instead') -const DateFormat$json = const { - '1': 'DateFormat', - '2': const [ - const {'1': 'Local', '2': 0}, - const {'1': 'US', '2': 1}, - const {'1': 'ISO', '2': 2}, - const {'1': 'Friendly', '2': 3}, - ], -}; - -/// Descriptor for `DateFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List dateFormatDescriptor = $convert.base64Decode('CgpEYXRlRm9ybWF0EgkKBUxvY2FsEAASBgoCVVMQARIHCgNJU08QAhIMCghGcmllbmRseRAD'); -@$core.Deprecated('Use timeFormatDescriptor instead') -const TimeFormat$json = const { - '1': 'TimeFormat', - '2': const [ - const {'1': 'TwelveHour', '2': 0}, - const {'1': 'TwentyFourHour', '2': 1}, - ], -}; - -/// Descriptor for `TimeFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List timeFormatDescriptor = $convert.base64Decode('CgpUaW1lRm9ybWF0Eg4KClR3ZWx2ZUhvdXIQABISCg5Ud2VudHlGb3VySG91chAB'); -@$core.Deprecated('Use moneySymbolDescriptor instead') -const MoneySymbol$json = const { - '1': 'MoneySymbol', - '2': const [ - const {'1': 'CNY', '2': 0}, - const {'1': 'EUR', '2': 1}, - const {'1': 'USD', '2': 2}, - ], -}; - -/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); -@$core.Deprecated('Use richTextDescriptionDescriptor instead') -const RichTextDescription$json = const { - '1': 'RichTextDescription', - '2': const [ - const {'1': 'format', '3': 1, '4': 1, '5': 9, '10': 'format'}, - ], -}; - -/// Descriptor for `RichTextDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List richTextDescriptionDescriptor = $convert.base64Decode('ChNSaWNoVGV4dERlc2NyaXB0aW9uEhYKBmZvcm1hdBgBIAEoCVIGZm9ybWF0'); -@$core.Deprecated('Use checkboxDescriptionDescriptor instead') -const CheckboxDescription$json = const { - '1': 'CheckboxDescription', - '2': const [ - const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, - ], -}; - -/// Descriptor for `CheckboxDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List checkboxDescriptionDescriptor = $convert.base64Decode('ChNDaGVja2JveERlc2NyaXB0aW9uEh8KC2lzX3NlbGVjdGVkGAEgASgIUgppc1NlbGVjdGVk'); -@$core.Deprecated('Use dateDescriptionDescriptor instead') -const DateDescription$json = const { - '1': 'DateDescription', - '2': const [ - const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'}, - const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'}, - ], -}; - -/// Descriptor for `DateDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List dateDescriptionDescriptor = $convert.base64Decode('Cg9EYXRlRGVzY3JpcHRpb24SLAoLZGF0ZV9mb3JtYXQYASABKA4yCy5EYXRlRm9ybWF0UgpkYXRlRm9ybWF0EiwKC3RpbWVfZm9ybWF0GAIgASgOMgsuVGltZUZvcm1hdFIKdGltZUZvcm1hdA=='); -@$core.Deprecated('Use singleSelectDescriptionDescriptor instead') -const SingleSelectDescription$json = const { - '1': 'SingleSelectDescription', - '2': const [ - const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, - const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, - ], -}; - -/// Descriptor for `SingleSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List singleSelectDescriptionDescriptor = $convert.base64Decode('ChdTaW5nbGVTZWxlY3REZXNjcmlwdGlvbhInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); -@$core.Deprecated('Use multiSelectDescriptionDescriptor instead') -const MultiSelectDescription$json = const { - '1': 'MultiSelectDescription', - '2': const [ - const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, - const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, - ], -}; - -/// Descriptor for `MultiSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List multiSelectDescriptionDescriptor = $convert.base64Decode('ChZNdWx0aVNlbGVjdERlc2NyaXB0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); -@$core.Deprecated('Use selectOptionDescriptor instead') -const SelectOption$json = const { - '1': 'SelectOption', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, - ], -}; - -/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); -@$core.Deprecated('Use numberDescriptionDescriptor instead') -const NumberDescription$json = const { - '1': 'NumberDescription', - '2': const [ - const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, - const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, - const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, - const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, - const {'1': 'name', '3': 5, '4': 1, '5': 9, '10': 'name'}, - ], -}; - -/// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart deleted file mode 100644 index b46de00bf5..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: type_options.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -export 'type_options.pb.dart'; - diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 61b69b45f1..2cc96e75d6 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -112,6 +112,7 @@ flutter: - assets/images/home/ - assets/images/editor/ - assets/images/grid/ + - assets/images/grid/field/ - assets/translations/ # - images/a_dot_ham.jpeg diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 59e3aa2a39..39d6bf2e95 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -71,6 +71,17 @@ pub(crate) async fn create_field_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn create_default_field_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let grid_id: GridId = data.into_inner(); + let editor = manager.get_grid_editor(grid_id.as_ref())?; + let field = editor.make_default_field().await?; + data_result(field) +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_row_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 944c58d13b..8c08d547ff 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -13,6 +13,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) + .event(GridEvent::CreateDefaultField, create_default_field_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); @@ -38,6 +39,9 @@ pub enum GridEvent { #[event(input = "CreateFieldPayload")] CreateField = 12, + #[event(input = "GridId", output = "Field")] + CreateDefaultField = 13, + #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 21, 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 0ba8fdebc4..4e0008c7a0 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 @@ -30,6 +30,7 @@ pub enum GridEvent { GetFields = 10, UpdateField = 11, CreateField = 12, + CreateDefaultField = 13, CreateRow = 21, GetRow = 22, UpdateCell = 30, @@ -47,6 +48,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 10 => ::std::option::Option::Some(GridEvent::GetFields), 11 => ::std::option::Option::Some(GridEvent::UpdateField), 12 => ::std::option::Option::Some(GridEvent::CreateField), + 13 => ::std::option::Option::Some(GridEvent::CreateDefaultField), 21 => ::std::option::Option::Some(GridEvent::CreateRow), 22 => ::std::option::Option::Some(GridEvent::GetRow), 30 => ::std::option::Option::Some(GridEvent::UpdateCell), @@ -61,6 +63,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetFields, GridEvent::UpdateField, GridEvent::CreateField, + GridEvent::CreateDefaultField, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, @@ -92,11 +95,11 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\x8b\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xa3\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ - \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\r\n\tCreate\ - Row\x10\x15\x12\n\n\x06GetRow\x10\x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06\ - proto3\ + \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x16\n\x12Cr\ + eateDefaultField\x10\r\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\x10\ + \x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index 2e768a115b..8408c120c1 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -4,9 +4,6 @@ mod number_type_option; pub use number_type_option::*; -mod text_description; -pub use text_description::*; - mod dart_notification; pub use dart_notification::*; @@ -19,5 +16,8 @@ pub use checkbox_type_option::*; mod event_map; pub use event_map::*; +mod text_type_option; +pub use text_type_option::*; + mod date_type_option; pub use date_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_type_option.rs similarity index 98% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/text_type_option.rs index 2bedb36f63..febc180e03 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_type_option.rs @@ -17,7 +17,7 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `text_description.proto` +//! Generated file from `text_type_option.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. @@ -183,7 +183,7 @@ impl ::protobuf::reflect::ProtobufValue for RichTextTypeOption { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x16text_description.proto\",\n\x12RichTextTypeOption\x12\x16\n\x06for\ + \n\x16text_type_option.proto\",\n\x12RichTextTypeOption\x12\x16\n\x06for\ mat\x18\x01\x20\x01(\tR\x06formatb\x06proto3\ "; 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 9a2177b6f4..894b2a111a 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 @@ -6,6 +6,7 @@ enum GridEvent { GetFields = 10; UpdateField = 11; CreateField = 12; + CreateDefaultField = 13; CreateRow = 21; GetRow = 22; UpdateCell = 30; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_type_option.proto similarity index 100% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/text_type_option.proto diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 14206f9254..64f5e40ee4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,19 +1,25 @@ +use crate::services::field::type_options::*; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; pub struct FieldBuilder { field_meta: FieldMeta, - type_options_builder: Box, + type_option_builder: Box, } impl FieldBuilder { - pub fn new(type_options_builder: T) -> Self { - let field_meta = FieldMeta::new("Name", "", FieldType::RichText); + pub fn new(type_option_builder: T) -> Self { + let field_meta = FieldMeta::new("", "", type_option_builder.field_type()); Self { field_meta, - type_options_builder: Box::new(type_options_builder), + type_option_builder: Box::new(type_option_builder), } } + pub fn from_field_type(field_type: &FieldType) -> Self { + let type_option_builder = type_option_builder_from_type(field_type); + Self::new(type_option_builder) + } + pub fn name(mut self, name: &str) -> Self { self.field_meta.name = name.to_owned(); self @@ -24,11 +30,6 @@ impl FieldBuilder { self } - pub fn field_type(mut self, field_type: FieldType) -> Self { - self.field_meta.field_type = field_type; - self - } - pub fn visibility(mut self, visibility: bool) -> Self { self.field_meta.visibility = visibility; self @@ -45,9 +46,8 @@ impl FieldBuilder { } pub fn build(mut self) -> FieldMeta { - assert_eq!(self.field_meta.field_type, self.type_options_builder.field_type()); - - let type_options = self.type_options_builder.build(); + debug_assert_eq!(self.field_meta.field_type, self.type_option_builder.field_type()); + let type_options = self.type_option_builder.build(); self.field_meta.type_option = type_options; self.field_meta } @@ -57,3 +57,27 @@ pub trait TypeOptionsBuilder { fn field_type(&self) -> FieldType; fn build(&self) -> String; } + +pub fn type_option_builder_from_type(field_type: &FieldType) -> Box { + match field_type { + FieldType::RichText => Box::new(RichTextTypeOptionBuilder::default()), + FieldType::Number => Box::new(NumberTypeOptionBuilder::default()), + FieldType::DateTime => Box::new(DateTypeOptionBuilder::default()), + FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::default()), + FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::default()), + FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::default()), + } +} + +impl TypeOptionsBuilder for Box +where + T: TypeOptionsBuilder + ?Sized, +{ + fn field_type(&self) -> FieldType { + (**self).field_type() + } + + fn build(&self) -> String { + (**self).build() + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index da6d057c03..08ae9f79c8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -7,15 +7,15 @@ use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; #[derive(Default)] -pub struct CheckboxTypeOptionsBuilder(CheckboxTypeOption); -impl CheckboxTypeOptionsBuilder { +pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption); +impl CheckboxTypeOptionBuilder { pub fn set_selected(mut self, is_selected: bool) -> Self { self.0.is_selected = is_selected; self } } -impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { +impl TypeOptionsBuilder for CheckboxTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } @@ -66,7 +66,7 @@ mod tests { #[test] fn checkout_box_description_test() { - let description = CheckboxTypeOption::default(); + let type_option = CheckboxTypeOption::default(); assert_eq!(description.serialize_cell_data("true").unwrap(), "1".to_owned()); assert_eq!(description.serialize_cell_data("1").unwrap(), "1".to_owned()); assert_eq!(description.serialize_cell_data("yes").unwrap(), "1".to_owned()); diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 8c8fec6a86..20d94c8ca8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -63,8 +63,8 @@ impl CellDataSerde for DateTypeOption { } #[derive(Default)] -pub struct DateTypeOptionsBuilder(DateTypeOption); -impl DateTypeOptionsBuilder { +pub struct DateTypeOptionBuilder(DateTypeOption); +impl DateTypeOptionBuilder { pub fn date_format(mut self, date_format: DateFormat) -> Self { self.0.date_format = date_format; self @@ -75,7 +75,7 @@ impl DateTypeOptionsBuilder { self } } -impl TypeOptionsBuilder for DateTypeOptionsBuilder { +impl TypeOptionsBuilder for DateTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } @@ -258,7 +258,7 @@ mod tests { #[test] #[should_panic] fn date_description_invalid_data_test() { - let description = DateTypeOption::default(); + let type_option = DateTypeOption::default(); description.serialize_cell_data("he").unwrap(); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs index 51d06fff19..958edf2664 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs @@ -2,10 +2,10 @@ mod checkbox_type_option; mod date_type_option; mod number_type_option; mod selection_type_option; -mod text_description; +mod text_type_option; pub use checkbox_type_option::*; pub use date_type_option::*; pub use number_type_option::*; pub use selection_type_option::*; -pub use text_description::*; +pub use text_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 64783cda2b..5fa74285df 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -19,9 +19,9 @@ lazy_static! { } #[derive(Default)] -pub struct NumberTypeOptionsBuilder(NumberTypeOption); +pub struct NumberTypeOptionBuilder(NumberTypeOption); -impl NumberTypeOptionsBuilder { +impl NumberTypeOptionBuilder { pub fn name(mut self, name: &str) -> Self { self.0.name = name.to_string(); self @@ -43,7 +43,7 @@ impl NumberTypeOptionsBuilder { } } -impl TypeOptionsBuilder for NumberTypeOptionsBuilder { +impl TypeOptionsBuilder for NumberTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index af5e58119f..5c4a3c5141 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -33,15 +33,15 @@ impl CellDataSerde for SingleSelectTypeOption { } #[derive(Default)] -pub struct SingleSelectTypeOptionsBuilder(SingleSelectTypeOption); +pub struct SingleSelectTypeOptionBuilder(SingleSelectTypeOption); -impl SingleSelectTypeOptionsBuilder { +impl SingleSelectTypeOptionBuilder { pub fn option(mut self, opt: SelectOption) -> Self { self.0.options.push(opt); self } } -impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { +impl TypeOptionsBuilder for SingleSelectTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } @@ -72,15 +72,15 @@ impl CellDataSerde for MultiSelectTypeOption { } #[derive(Default)] -pub struct MultiSelectTypeOptionsBuilder(MultiSelectTypeOption); -impl MultiSelectTypeOptionsBuilder { +pub struct MultiSelectTypeOptionBuilder(MultiSelectTypeOption); +impl MultiSelectTypeOptionBuilder { pub fn option(mut self, opt: SelectOption) -> Self { self.0.options.push(opt); self } } -impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { +impl TypeOptionsBuilder for MultiSelectTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } @@ -157,10 +157,10 @@ mod tests { #[test] #[should_panic] fn selection_description_test() { - let description = SingleSelectTypeOption::default(); + let type_option = SingleSelectTypeOption::default(); assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); - let description = MultiSelectDescription::default(); + let type_option = MultiSelectDescription::default(); assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs similarity index 90% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/text_description.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 9b6b988fc0..dc7e0e56d0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -8,9 +8,9 @@ use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; #[derive(Default)] -pub struct RichTextTypeOptionsBuilder(RichTextTypeOption); +pub struct RichTextTypeOptionBuilder(RichTextTypeOption); -impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { +impl TypeOptionsBuilder for RichTextTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } 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 80768c5251..2582ad77b0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,25 +1,19 @@ +use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; +use crate::services::field::{type_option_builder_from_type, FieldBuilder}; +use crate::services::row::*; use bytes::Bytes; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, - RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, Row, RowMeta, RowMetaChangeset, RowOrder, -}; +use flowy_grid_data_model::entities::*; +use flowy_grid_data_model::parser::CreateFieldParams; +use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use flowy_sync::client_grid::{GridChangeset, GridMetaPad}; use flowy_sync::entities::revision::Revision; use flowy_sync::util::make_delta_from_revisions; -use std::collections::HashMap; - -use crate::dart_notification::{send_dart_notification, GridNotification}; -use crate::services::row::{ - make_grid_block_from_block_metas, make_grid_blocks, make_row_meta_from_context, make_rows_from_row_metas, - serialize_cell_data, CreateRowMetaBuilder, CreateRowMetaPayload, GridBlockMetaData, -}; -use flowy_grid_data_model::parser::CreateFieldParams; -use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; +use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; @@ -55,12 +49,25 @@ impl ClientGridEditor { })) } - pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> { + pub async fn create_field(&self, mut params: CreateFieldParams) -> FlowyResult<()> { + if params.type_option_data.is_empty() { + params.type_option_data = type_option_builder_from_type(¶ms.field.field_type) + .build() + .as_bytes() + .to_vec(); + } + let _ = self.modify(|grid| Ok(grid.create_field(params)?)).await?; let _ = self.notify_did_update_fields().await?; Ok(()) } + pub async fn make_default_field(&self) -> FlowyResult { + let field_type = FieldType::default(); + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + Ok(field_meta.into()) + } + pub async fn contain_field(&self, field_id: &str) -> bool { self.pad.read().await.contain_field(field_id) } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 9349854433..1638060f61 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -3,22 +3,17 @@ use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; use flowy_sync::client_grid::GridBuilder; pub fn make_default_grid() -> BuildGridContext { - let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) + let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default()) .name("Name") .visibility(true) - .field_type(FieldType::RichText) .build(); - let single_select = SingleSelectTypeOptionsBuilder::default() + let single_select = SingleSelectTypeOptionBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Unknown")) .option(SelectOption::new("Progress")); - let single_select_field = FieldBuilder::new(single_select) - .name("Status") - .visibility(true) - .field_type(FieldType::SingleSelect) - .build(); + let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build(); GridBuilder::default() .add_field(text_field) diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 803c2409a9..4cda3a599e 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -253,13 +253,13 @@ async fn grid_row_add_cells_test() { builder.add_cell(&field.id, data).unwrap(); } FieldType::SingleSelect => { - let description = SingleSelectTypeOption::from(field); + let type_option = SingleSelectTypeOption::from(field); let options = description.options.first().unwrap(); let data = description.serialize_cell_data(&options.id).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { - let description = MultiSelectTypeOption::from(field); + let type_option = MultiSelectTypeOption::from(field); let options = description .options .iter() @@ -382,11 +382,11 @@ async fn grid_cell_update() { FieldType::Number => "123".to_string(), FieldType::DateTime => "123".to_string(), FieldType::SingleSelect => { - let description = SingleSelectTypeOption::from(field_meta); + let type_option = SingleSelectTypeOption::from(field_meta); description.options.first().unwrap().id.clone() } FieldType::MultiSelect => { - let description = MultiSelectTypeOption::from(field_meta); + let type_option = MultiSelectTypeOption::from(field_meta); description.options.first().unwrap().id.clone() } FieldType::Checkbox => "1".to_string(), diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index fa25ef3e78..d622d3acbe 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -248,10 +248,9 @@ async fn get_row_metas(editor: &Arc) -> Vec> { } pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { - let field_meta = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) + let field_meta = FieldBuilder::new(RichTextTypeOptionBuilder::default()) .name("Name") .visibility(true) - .field_type(FieldType::RichText) .build(); let cloned_field_meta = field_meta.clone(); @@ -276,16 +275,11 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { } pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { - let single_select = SingleSelectTypeOptionsBuilder::default() + let single_select = SingleSelectTypeOptionBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); - let field_meta = FieldBuilder::new(single_select) - .name("Name") - .visibility(true) - .field_type(FieldType::SingleSelect) - .build(); - + let field_meta = FieldBuilder::new(single_select).name("Name").visibility(true).build(); let cloned_field_meta = field_meta.clone(); let field = Field { @@ -308,60 +302,42 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet } fn make_template_1_grid() -> BuildGridContext { - let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) + let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default()) .name("Name") .visibility(true) - .field_type(FieldType::RichText) .build(); // Single Select - let single_select = SingleSelectTypeOptionsBuilder::default() + let single_select = SingleSelectTypeOptionBuilder::default() .option(SelectOption::new("Live")) .option(SelectOption::new("Completed")) .option(SelectOption::new("Planned")) .option(SelectOption::new("Paused")); - let single_select_field = FieldBuilder::new(single_select) - .name("Status") - .visibility(true) - .field_type(FieldType::SingleSelect) - .build(); + let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build(); // MultiSelect - let multi_select = MultiSelectTypeOptionsBuilder::default() + let multi_select = MultiSelectTypeOptionBuilder::default() .option(SelectOption::new("Google")) .option(SelectOption::new("Facebook")) .option(SelectOption::new("Twitter")); let multi_select_field = FieldBuilder::new(multi_select) .name("Platform") .visibility(true) - .field_type(FieldType::MultiSelect) .build(); // Number - let number = NumberTypeOptionsBuilder::default().set_format(NumberFormat::USD); - let number_field = FieldBuilder::new(number) - .name("Price") - .visibility(true) - .field_type(FieldType::Number) - .build(); + let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD); + let number_field = FieldBuilder::new(number).name("Price").visibility(true).build(); // Date - let date = DateTypeOptionsBuilder::default() + let date = DateTypeOptionBuilder::default() .date_format(DateFormat::US) .time_format(TimeFormat::TwentyFourHour); - let date_field = FieldBuilder::new(date) - .name("Time") - .visibility(true) - .field_type(FieldType::DateTime) - .build(); + let date_field = FieldBuilder::new(date).name("Time").visibility(true).build(); // Checkbox - let checkbox = CheckboxTypeOptionsBuilder::default(); - let checkbox_field = FieldBuilder::new(checkbox) - .name("is done") - .visibility(true) - .field_type(FieldType::Checkbox) - .build(); + let checkbox = CheckboxTypeOptionBuilder::default(); + let checkbox_field = FieldBuilder::new(checkbox).name("is done").visibility(true).build(); GridBuilder::default() .add_field(text_field) diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs b/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs index bfcb802c22..83f0395f53 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs @@ -102,10 +102,6 @@ impl TryInto for CreateFieldPayload { Some(id) => Some(NotEmptyUuid::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), }; - if self.type_option_data.is_empty() { - return Err(ErrorCode::TypeOptionIsEmpty); - } - Ok(CreateFieldParams { grid_id: grid_id.0, field: self.field, diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 372433cd34..06ecf07030 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -45,16 +45,18 @@ impl GridMetaPad { .. } = params; + // Check if the field exists or not if grid .fields .iter() .find(|field_meta| field_meta.id == field.id) .is_some() { - tracing::warn!("Create grid field"); + tracing::warn!("Duplicate grid field"); return Ok(None); } + // Parse type option let type_option = String::from_utf8(type_option_data).map_err(|e| CollaborateError::internal().context(e))?; From 2eccd0452bd0ef5d8369803cc313b0263b5378a1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 24 Mar 2022 23:52:06 +0800 Subject: [PATCH 059/179] chore: close bloc when overlay dismiss --- .../app_flowy/assets/translations/en.json | 2 +- .../grid/field/create_field_bloc.dart | 11 ++- .../application/grid/field/field_service.dart | 20 +++-- .../widgets/header/create_field_pannel.dart | 78 ++++++++++++------- .../widgets/header/field_operation_list.dart | 2 - .../widgets/header/field_tyep_switcher.dart | 3 +- .../src/widgets/header/field_type_list.dart | 1 - .../grid/src/widgets/header/header.dart | 12 +-- .../lib/style_widget/button.dart | 2 +- .../flowy_infra_ui/lib/style_widget/text.dart | 3 +- .../lib/widget/rounded_input_field.dart | 1 + .../flowy-grid/src/services/grid_editor.rs | 3 +- 12 files changed, 83 insertions(+), 55 deletions(-) diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 5646cdff58..5e5fc661ec 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -150,7 +150,7 @@ "duplicate": "Duplicate", "delete": "Delete", "textFieldName": "Text", - "checkboxFieldName": "Number", + "checkboxFieldName": "Checkbox", "dateFieldName": "Date", "numberFieldName": "Number", "singleSelectFieldName": "Select", diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart index 0d9126cd1e..9f70646415 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -14,8 +15,15 @@ class CreateFieldBloc extends Bloc { on( (event, emit) async { await event.map( - initial: (_InitialField value) {}, + initial: (_InitialField value) async { + final result = await service.getDefaultField(); + result.fold( + (field) => emit(state.copyWith(field: Some(field))), + (err) => Log.error(err), + ); + }, updateName: (_UpdateName value) {}, + done: (_Done value) {}, ); }, ); @@ -31,6 +39,7 @@ class CreateFieldBloc extends Bloc { class CreateFieldEvent with _$CreateFieldEvent { const factory CreateFieldEvent.initial() = _InitialField; const factory CreateFieldEvent.updateName(String newName) = _UpdateName; + const factory CreateFieldEvent.done() = _Done; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 5a8032b79a..f63d8d5d5f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -12,9 +12,7 @@ class FieldService { FieldService({required this.gridId}); - Future> getDefaultField( - String gridId, - ) { + Future> getDefaultField() { final payload = GridId.create()..value = gridId; return GridEventCreateDefaultField(payload).send(); } @@ -26,7 +24,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return _createField(gridId, field, typeOptionData, startFieldId); + return createField(gridId, field, typeOptionData, startFieldId); } Future> createSingleSelectField( @@ -36,7 +34,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return _createField(gridId, field, typeOptionData, startFieldId); + return createField(gridId, field, typeOptionData, startFieldId); } Future> createMultiSelectField( @@ -46,7 +44,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return _createField(gridId, field, typeOptionData, startFieldId); + return createField(gridId, field, typeOptionData, startFieldId); } Future> createNumberField( @@ -56,7 +54,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return _createField(gridId, field, typeOptionData, startFieldId); + return createField(gridId, field, typeOptionData, startFieldId); } Future> createDateField( @@ -66,19 +64,19 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return _createField(gridId, field, typeOptionData, startFieldId); + return createField(gridId, field, typeOptionData, startFieldId); } - Future> _createField( + Future> createField( String gridId, Field field, - Uint8List typeOptionData, + Uint8List? typeOptionData, String? startFieldId, ) { final payload = CreateFieldPayload.create() ..gridId = gridId ..field_2 = field - ..typeOptionData = typeOptionData + ..typeOptionData = typeOptionData ?? Uint8List.fromList([]) ..startFieldId = startFieldId ?? ""; return GridEventCreateField(payload).send(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index 69d57782a8..0b8e2c3eac 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -3,55 +3,73 @@ import 'package:app_flowy/workspace/application/grid/field/create_field_bloc.dar import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - import 'field_name_input.dart'; import 'field_tyep_switcher.dart'; -class CreateFieldPannel extends StatelessWidget { - const CreateFieldPannel({Key? key}) : super(key: key); +class CreateFieldPannel extends FlowyOverlayDelegate { + final String gridId; + final CreateFieldBloc _createFieldBloc; + CreateFieldPannel({required this.gridId, Key? key}) : _createFieldBloc = getIt(param1: gridId) { + _createFieldBloc.add(const CreateFieldEvent.initial()); + } - static void show(BuildContext context) { - const pannel = CreateFieldPannel(); + void show(BuildContext context, String gridId) { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( - child: pannel, - constraints: BoxConstraints.loose(const Size(300, 200)), + child: _CreateFieldPannelWidget(_createFieldBloc), + constraints: BoxConstraints.loose(const Size(220, 200)), ), - identifier: pannel.identifier(), + identifier: identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomWithLeftAligned, style: FlowyOverlayStyle(blur: false), - ); - } - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt()..add(const CreateFieldEvent.initial()), - child: BlocBuilder( - builder: (context, state) { - return state.field.fold( - () => const SizedBox(), - (field) => Column(children: [ - const FlowyText.medium("Edit property"), - const VSpace(10), - _FieldNameTextField(field), - const VSpace(10), - _FieldTypeSwitcher(field), - ]), - ); - }, - ), + delegate: this, ); } String identifier() { return toString(); } + + @override + void didRemove() async { + await _createFieldBloc.close(); + // TODO: implement didRemove + } +} + +class _CreateFieldPannelWidget extends StatelessWidget { + final CreateFieldBloc createFieldBloc; + const _CreateFieldPannelWidget(this.createFieldBloc, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: createFieldBloc, + child: BlocBuilder( + builder: (context, state) { + return state.field.fold( + () => const SizedBox(), + (field) => ListView( + shrinkWrap: true, + children: [ + const FlowyText.medium("Edit property", fontSize: 12), + const VSpace(10), + _FieldNameTextField(field), + const VSpace(10), + _FieldTypeSwitcher(field), + const VSpace(10), + ], + ), + ); + }, + ), + ); + } } class _FieldTypeSwitcher extends StatelessWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart index f803bdee58..fb639e5f5b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart @@ -55,9 +55,7 @@ class FieldActionItem extends StatelessWidget { enum FieldAction { hide, - // insertLeft, duplicate, - // insertRight, delete, } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index 505715d541..61b7c49b2d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -26,7 +26,8 @@ class FieldTypeSwitcher extends StatelessWidget { return SizedBox( height: 36, child: FlowyButton( - text: FlowyText.medium(field.name, fontSize: 12), + text: FlowyText.medium(field.fieldType.title(), fontSize: 12), + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), hoverColor: theme.hover, onTap: () => FieldTypeList.show(context, onSelectField), leftIcon: svg(field.fieldType.iconName(), color: theme.iconColor), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index aa5d22804d..25ff77494d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -1,4 +1,3 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 1b1cde2acb..cfac576cd5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -65,7 +65,7 @@ class GridHeader extends StatelessWidget { children: [ const _HeaderLeading(), ...cells, - const _HeaderTrailing(), + _HeaderTrailing(gridId: gridId), ], ); @@ -88,7 +88,8 @@ class _HeaderLeading extends StatelessWidget { } class _HeaderTrailing extends StatelessWidget { - const _HeaderTrailing({Key? key}) : super(key: key); + final String gridId; + const _HeaderTrailing({required this.gridId, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -100,13 +101,14 @@ class _HeaderTrailing extends StatelessWidget { border: Border(top: borderSide, bottom: borderSide), ), padding: GridSize.headerContentInsets, - child: const CreateFieldButton(), + child: CreateFieldButton(gridId: gridId), ); } } class CreateFieldButton extends StatelessWidget { - const CreateFieldButton({Key? key}) : super(key: key); + final String gridId; + const CreateFieldButton({required this.gridId, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -114,7 +116,7 @@ class CreateFieldButton extends StatelessWidget { return FlowyButton( text: const FlowyText.medium('New column', fontSize: 12), hoverColor: theme.hover, - onTap: () => CreateFieldPannel.show(context), + onTap: () => CreateFieldPannel(gridId: gridId).show(context, gridId), leftIcon: svg("home/add"), ); } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index d74edefba4..78d65a9941 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -40,7 +40,7 @@ class FlowyButton extends StatelessWidget { children.add(const HSpace(6)); } - children.add(Align(child: text)); + children.add(text); if (rightIcon != null) { children.add(const Spacer()); diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart index 243cf37b7a..7ddfdc1c13 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart @@ -1,5 +1,5 @@ import 'package:flowy_infra/theme.dart'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class FlowyText extends StatelessWidget { @@ -42,6 +42,7 @@ class FlowyText extends StatelessWidget { return Text(title, overflow: overflow, softWrap: false, + textAlign: textAlign, style: TextStyle( color: theme.textColor, fontWeight: fontWeight, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index 0cd2265cce..110cd29c73 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -81,6 +81,7 @@ class _RoundedInputFieldState extends State { }, cursorColor: widget.cursorColor, obscureText: obscuteText, + style: widget.style, decoration: InputDecoration( contentPadding: widget.contentPadding, hintText: widget.hintText, 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 2582ad77b0..d81b96a1ad 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -64,7 +64,8 @@ impl ClientGridEditor { pub async fn make_default_field(&self) -> FlowyResult { let field_type = FieldType::default(); - let field_meta = FieldBuilder::from_field_type(&field_type).build(); + let name = format!("Property {}", self.pad.read().await.fields().len()); + let field_meta = FieldBuilder::from_field_type(&field_type).name(&name).build(); Ok(field_meta.into()) } From 90e7873135fa9554b41b1700cde92b0effa3902c Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 25 Mar 2022 15:02:43 +0800 Subject: [PATCH 060/179] chore: create field --- .../app_flowy/lib/startup/deps_resolver.dart | 222 ++++++++ .../lib/startup/home_deps_resolver.dart | 169 ------ frontend/app_flowy/lib/startup/startup.dart | 6 +- .../lib/startup/user_deps_resolver.dart | 29 -- .../lib/user/application/prelude.dart | 4 + .../lib/user/application/sign_in_bloc.dart | 4 +- .../lib/user/application/sign_up_bloc.dart | 12 +- .../app_flowy/lib/user/domain/auth_state.dart | 2 +- .../grid/cell_bloc/checkbox_cell_bloc.dart | 4 +- .../grid/cell_bloc/date_cell_bloc.dart | 4 +- .../grid/cell_bloc/number_cell_bloc.dart | 4 +- .../grid/cell_bloc/selection_cell_bloc.dart | 4 +- .../grid/cell_bloc/text_cell_bloc.dart | 4 +- .../grid/field/create_field_bloc.dart | 9 +- .../grid/field/edit_field_bloc.dart | 9 +- .../application/grid/field/field_service.dart | 21 +- .../grid/field/switch_field_type_bloc.dart | 61 +++ .../grid/field/type_option/date_bloc.dart | 39 ++ .../grid/field/type_option/number_bloc.dart | 39 ++ .../field/type_option/selection_bloc.dart | 39 ++ .../workspace/application/grid/grid_bloc.dart | 4 +- .../workspace/application/grid/prelude.dart | 10 + .../application/grid/row/row_bloc.dart | 2 +- .../src/widgets/content/cell_builder.dart | 2 +- .../widgets/header/create_field_pannel.dart | 24 +- .../grid/src/widgets/header/field_editor.dart | 12 +- .../src/widgets/header/field_name_input.dart | 2 +- .../widgets/header/field_tyep_switcher.dart | 199 +++++++- .../src/widgets/header/field_type_list.dart | 6 +- .../src/flowy_overlay/overlay_container.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 12 +- .../flowy-grid-data-model/grid.pb.dart | 138 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 23 + .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 28 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- .../src/protobuf/model/event_map.rs | 14 +- .../src/protobuf/proto/event_map.proto | 2 +- .../flowy-grid/src/services/grid_editor.rs | 5 +- .../src/entities/grid.rs | 21 + .../src/protobuf/model/grid.rs | 483 +++++++++++++++++- .../src/protobuf/proto/grid.proto | 9 + 43 files changed, 1371 insertions(+), 326 deletions(-) create mode 100644 frontend/app_flowy/lib/startup/deps_resolver.dart delete mode 100644 frontend/app_flowy/lib/startup/home_deps_resolver.dart delete mode 100644 frontend/app_flowy/lib/startup/user_deps_resolver.dart create mode 100644 frontend/app_flowy/lib/user/application/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart new file mode 100644 index 0000000000..56f115a22b --- /dev/null +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -0,0 +1,222 @@ +import 'package:app_flowy/core/network_monitor.dart'; +import 'package:app_flowy/user/application/user_listener.dart'; +import 'package:app_flowy/user/application/user_service.dart'; +import 'package:app_flowy/workspace/application/app/prelude.dart'; +import 'package:app_flowy/workspace/application/doc/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_listener.dart'; +import 'package:app_flowy/workspace/application/trash/prelude.dart'; +import 'package:app_flowy/workspace/application/workspace/prelude.dart'; +import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart'; +import 'package:app_flowy/workspace/application/home/home_bloc.dart'; +import 'package:app_flowy/workspace/application/view/prelude.dart'; +import 'package:app_flowy/workspace/application/home/prelude.dart'; +import 'package:app_flowy/workspace/application/menu/prelude.dart'; +import 'package:app_flowy/user/application/prelude.dart'; +import 'package:app_flowy/user/presentation/router.dart'; +import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; +import 'package:get_it/get_it.dart'; + +class DependencyResolver { + static Future resolve(GetIt getIt) async { + _resolveUserDeps(getIt); + + _resolveHomeDeps(getIt); + + _resolveFolderDeps(getIt); + + _resolveDocDeps(getIt); + + _resolveGridDeps(getIt); + } +} + +void _resolveUserDeps(GetIt getIt) { + getIt.registerFactory(() => AuthService()); + getIt.registerFactory(() => AuthRouter()); + + getIt.registerFactory(() => SignInBloc(getIt())); + getIt.registerFactory(() => SignUpBloc(getIt())); + + getIt.registerFactory(() => SplashRoute()); + getIt.registerFactory(() => HomeBloc()); + getIt.registerFactory(() => EditPannelBloc()); + getIt.registerFactory(() => SplashBloc()); + getIt.registerLazySingleton(() => NetworkListener()); +} + +void _resolveHomeDeps(GetIt getIt) { + getIt.registerFactoryParam( + (user, _) => UserListener(user: user), + ); + + getIt.registerFactoryParam( + (user, _) => HomeListenBloc(getIt(param1: user)), + ); + + // + getIt.registerLazySingleton(() => HomeStackManager()); + + getIt.registerFactoryParam( + (user, _) => WelcomeBloc( + userService: UserService(), + userListener: getIt(param1: user), + ), + ); + + // share + getIt.registerLazySingleton(() => ShareService()); + getIt.registerFactoryParam( + (view, _) => DocShareBloc(view: view, service: getIt())); +} + +void _resolveFolderDeps(GetIt getIt) { + //workspace + getIt.registerFactoryParam((user, workspaceId) => + WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId))); + + // View + getIt.registerFactoryParam( + (view, _) => ViewListener(view: view), + ); + + getIt.registerFactoryParam( + (view, _) => ViewBloc( + view: view, + service: ViewService(), + listener: getIt(param1: view), + ), + ); + + //Menu + getIt.registerFactoryParam( + (user, workspaceId) => MenuBloc( + workspaceId: workspaceId, + service: WorkspaceService(), + listener: getIt(param1: user, param2: workspaceId), + ), + ); + + getIt.registerFactoryParam( + (user, _) => MenuUserBloc( + user, + UserService(), + getIt(param1: user), + ), + ); + + // App + getIt.registerFactoryParam( + (app, _) => AppBloc( + app: app, + service: AppService(), + listener: AppListener(appId: app.id), + ), + ); + + // trash + getIt.registerLazySingleton(() => TrashService()); + getIt.registerLazySingleton(() => TrashListener()); + getIt.registerFactory( + () => TrashBloc( + service: getIt(), + listener: getIt(), + ), + ); +} + +void _resolveDocDeps(GetIt getIt) { +// Doc + getIt.registerFactoryParam( + (view, _) => DocumentBloc( + view: view, + service: DocumentService(), + listener: getIt(param1: view), + trashService: getIt(), + ), + ); +} + +void _resolveGridDeps(GetIt getIt) { + // Grid + getIt.registerFactoryParam( + (view, _) => GridBloc(view: view, service: GridService()), + ); + + getIt.registerFactoryParam( + (data, _) => RowBloc( + rowService: RowService(data), + listener: RowListener(rowId: data.rowId), + ), + ); + + getIt.registerFactoryParam>( + (gridId, fields) => GridHeaderBloc( + data: GridHeaderData(gridId: gridId, fields: fields), + service: FieldService(gridId: gridId), + ), + ); + + getIt.registerFactoryParam( + (data, _) => EditFieldBloc( + field: data.field, + service: FieldService(gridId: data.gridId), + ), + ); + + getIt.registerFactoryParam( + (gridId, _) => CreateFieldBloc( + service: FieldService(gridId: gridId), + ), + ); + + getIt.registerFactoryParam( + (context, _) => TextCellBloc( + service: CellService(context), + ), + ); + + getIt.registerFactoryParam( + (context, _) => SelectionCellBloc( + service: CellService(context), + ), + ); + + getIt.registerFactoryParam( + (context, _) => NumberCellBloc( + service: CellService(context), + ), + ); + + getIt.registerFactoryParam( + (context, _) => DateCellBloc( + service: CellService(context), + ), + ); + + getIt.registerFactoryParam( + (context, _) => CheckboxCellBloc( + service: CellService(context), + ), + ); + + getIt.registerFactoryParam( + (editContext, _) => SwitchFieldTypeBloc(editContext), + ); + + getIt.registerFactory( + () => SelectionTypeOptionBloc(), + ); + + getIt.registerFactory( + () => DateTypeOptionBloc(), + ); + + getIt.registerFactory( + () => NumberTypeOptionBloc(), + ); +} diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart deleted file mode 100644 index 1702544a64..0000000000 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ /dev/null @@ -1,169 +0,0 @@ -import 'package:app_flowy/user/application/user_listener.dart'; -import 'package:app_flowy/user/application/user_service.dart'; -import 'package:app_flowy/workspace/application/app/prelude.dart'; -import 'package:app_flowy/workspace/application/doc/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/row/row_listener.dart'; -import 'package:app_flowy/workspace/application/trash/prelude.dart'; -import 'package:app_flowy/workspace/application/workspace/prelude.dart'; -import 'package:app_flowy/workspace/application/view/prelude.dart'; -import 'package:app_flowy/workspace/application/home/prelude.dart'; -import 'package:app_flowy/workspace/application/menu/prelude.dart'; - -import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; -import 'package:get_it/get_it.dart'; - -class HomeDepsResolver { - static Future resolve(GetIt getIt) async { - getIt.registerFactoryParam( - (user, _) => UserListener(user: user), - ); - - getIt.registerFactoryParam( - (user, _) => HomeListenBloc(getIt(param1: user)), - ); - - // - getIt.registerLazySingleton(() => HomeStackManager()); - getIt.registerFactoryParam( - (user, _) => WelcomeBloc( - userService: UserService(), - userListener: getIt(param1: user), - ), - ); - - //workspace - getIt.registerFactoryParam((user, workspaceId) => - WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId))); - - // View - getIt.registerFactoryParam( - (view, _) => ViewListener(view: view), - ); - - getIt.registerFactoryParam( - (view, _) => ViewBloc( - view: view, - service: ViewService(), - listener: getIt(param1: view), - ), - ); - - //Menu Bloc - getIt.registerFactoryParam( - (user, workspaceId) => MenuBloc( - workspaceId: workspaceId, - service: WorkspaceService(), - listener: getIt(param1: user, param2: workspaceId), - ), - ); - - getIt.registerFactoryParam( - (user, _) => MenuUserBloc( - user, - UserService(), - getIt(param1: user), - ), - ); - - // App - getIt.registerFactoryParam( - (app, _) => AppBloc( - app: app, - service: AppService(), - listener: AppListener(appId: app.id), - ), - ); - - // Doc - getIt.registerFactoryParam( - (view, _) => DocumentBloc( - view: view, - service: DocumentService(), - listener: getIt(param1: view), - trashService: getIt(), - ), - ); - - // Grid - getIt.registerFactoryParam( - (view, _) => GridBloc(view: view, service: GridService()), - ); - - getIt.registerFactoryParam( - (data, _) => RowBloc( - rowService: RowService(data), - listener: RowListener(rowId: data.rowId), - ), - ); - - getIt.registerFactoryParam>( - (gridId, fields) => GridHeaderBloc( - data: GridHeaderData(gridId: gridId, fields: fields), - service: FieldService(gridId: gridId), - ), - ); - - getIt.registerFactoryParam( - (data, _) => EditFieldBloc( - field: data.field, - service: FieldService(gridId: data.gridId), - ), - ); - - getIt.registerFactoryParam( - (gridId, _) => CreateFieldBloc( - service: FieldService(gridId: gridId), - ), - ); - - getIt.registerFactoryParam( - (context, _) => TextCellBloc( - service: CellService(context), - ), - ); - - getIt.registerFactoryParam( - (context, _) => SelectionCellBloc( - service: CellService(context), - ), - ); - - getIt.registerFactoryParam( - (context, _) => NumberCellBloc( - service: CellService(context), - ), - ); - - getIt.registerFactoryParam( - (context, _) => DateCellBloc( - service: CellService(context), - ), - ); - - getIt.registerFactoryParam( - (context, _) => CheckboxCellBloc( - service: CellService(context), - ), - ); - - // trash - getIt.registerLazySingleton(() => TrashService()); - getIt.registerLazySingleton(() => TrashListener()); - getIt.registerFactory( - () => TrashBloc( - service: getIt(), - listener: getIt(), - ), - ); - - // share - getIt.registerLazySingleton(() => ShareService()); - getIt.registerFactoryParam( - (view, _) => DocShareBloc(view: view, service: getIt())); - } -} diff --git a/frontend/app_flowy/lib/startup/startup.dart b/frontend/app_flowy/lib/startup/startup.dart index 0335879f5a..38243afa56 100644 --- a/frontend/app_flowy/lib/startup/startup.dart +++ b/frontend/app_flowy/lib/startup/startup.dart @@ -2,8 +2,7 @@ import 'dart:io'; import 'package:app_flowy/plugin/plugin.dart'; import 'package:app_flowy/startup/tasks/prelude.dart'; -import 'package:app_flowy/startup/home_deps_resolver.dart'; -import 'package:app_flowy/startup/user_deps_resolver.dart'; +import 'package:app_flowy/startup/deps_resolver.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; @@ -62,8 +61,7 @@ Future initGetIt( getIt.registerLazySingleton(() => AppLauncher(env, getIt)); getIt.registerSingleton(PluginSandbox()); - await UserDepsResolver.resolve(getIt); - await HomeDepsResolver.resolve(getIt); + await DependencyResolver.resolve(getIt); } class LaunchContext { diff --git a/frontend/app_flowy/lib/startup/user_deps_resolver.dart b/frontend/app_flowy/lib/startup/user_deps_resolver.dart deleted file mode 100644 index daf67a071a..0000000000 --- a/frontend/app_flowy/lib/startup/user_deps_resolver.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:app_flowy/user/application/auth_service.dart'; -import 'package:app_flowy/user/application/sign_in_bloc.dart'; -import 'package:app_flowy/user/application/sign_up_bloc.dart'; -import 'package:app_flowy/user/application/splash_bloc.dart'; -import 'package:app_flowy/user/presentation/router.dart'; -import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart'; -import 'package:app_flowy/workspace/application/home/home_bloc.dart'; -import 'package:get_it/get_it.dart'; - -import '../core/network_monitor.dart'; - -class UserDepsResolver { - static Future resolve(GetIt getIt) async { - getIt.registerFactory(() => AuthService()); - - //Interface implementation - getIt.registerFactory(() => AuthRouter()); - - //Bloc - getIt.registerFactory(() => SignInBloc(getIt())); - getIt.registerFactory(() => SignUpBloc(getIt())); - - getIt.registerFactory(() => SplashRoute()); - getIt.registerFactory(() => HomeBloc()); - getIt.registerFactory(() => EditPannelBloc()); - getIt.registerFactory(() => SplashBloc()); - getIt.registerLazySingleton(() => NetworkListener()); - } -} diff --git a/frontend/app_flowy/lib/user/application/prelude.dart b/frontend/app_flowy/lib/user/application/prelude.dart new file mode 100644 index 0000000000..74b644808e --- /dev/null +++ b/frontend/app_flowy/lib/user/application/prelude.dart @@ -0,0 +1,4 @@ +export './auth_service.dart'; +export './sign_in_bloc.dart'; +export './sign_up_bloc.dart'; +export './splash_bloc.dart'; diff --git a/frontend/app_flowy/lib/user/application/sign_in_bloc.dart b/frontend/app_flowy/lib/user/application/sign_in_bloc.dart index 25aa66cc50..e0f5bed605 100644 --- a/frontend/app_flowy/lib/user/application/sign_in_bloc.dart +++ b/frontend/app_flowy/lib/user/application/sign_in_bloc.dart @@ -54,14 +54,14 @@ class SignInBloc extends Bloc { } @freezed -abstract class SignInEvent with _$SignInEvent { +class SignInEvent with _$SignInEvent { const factory SignInEvent.signedInWithUserEmailAndPassword() = SignedInWithUserEmailAndPassword; const factory SignInEvent.emailChanged(String email) = EmailChanged; const factory SignInEvent.passwordChanged(String password) = PasswordChanged; } @freezed -abstract class SignInState with _$SignInState { +class SignInState with _$SignInState { const factory SignInState({ String? email, String? password, diff --git a/frontend/app_flowy/lib/user/application/sign_up_bloc.dart b/frontend/app_flowy/lib/user/application/sign_up_bloc.dart index 11acd1d385..2efc82d3c7 100644 --- a/frontend/app_flowy/lib/user/application/sign_up_bloc.dart +++ b/frontend/app_flowy/lib/user/application/sign_up_bloc.dart @@ -15,11 +15,11 @@ class SignUpBloc extends Bloc { on((event, emit) async { await event.map(signUpWithUserEmailAndPassword: (e) async { await _performActionOnSignUp(emit); - }, emailChanged: (EmailChanged value) async { + }, emailChanged: (_EmailChanged value) async { emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none())); - }, passwordChanged: (PasswordChanged value) async { + }, passwordChanged: (_PasswordChanged value) async { emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none())); - }, repeatPasswordChanged: (RepeatPasswordChanged value) async { + }, repeatPasswordChanged: (_RepeatPasswordChanged value) async { emit(state.copyWith(repeatedPassword: value.password, repeatPasswordError: none(), successOrFail: none())); }); }); @@ -104,9 +104,9 @@ class SignUpBloc extends Bloc { @freezed class SignUpEvent with _$SignUpEvent { const factory SignUpEvent.signUpWithUserEmailAndPassword() = SignUpWithUserEmailAndPassword; - const factory SignUpEvent.emailChanged(String email) = EmailChanged; - const factory SignUpEvent.passwordChanged(String password) = PasswordChanged; - const factory SignUpEvent.repeatPasswordChanged(String password) = RepeatPasswordChanged; + const factory SignUpEvent.emailChanged(String email) = _EmailChanged; + const factory SignUpEvent.passwordChanged(String password) = _PasswordChanged; + const factory SignUpEvent.repeatPasswordChanged(String password) = _RepeatPasswordChanged; } @freezed diff --git a/frontend/app_flowy/lib/user/domain/auth_state.dart b/frontend/app_flowy/lib/user/domain/auth_state.dart index b70383c0aa..96f2036e01 100644 --- a/frontend/app_flowy/lib/user/domain/auth_state.dart +++ b/frontend/app_flowy/lib/user/domain/auth_state.dart @@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'auth_state.freezed.dart'; @freezed -abstract class AuthState with _$AuthState { +class AuthState with _$AuthState { const factory AuthState.authenticated(UserProfile userProfile) = Authenticated; const factory AuthState.unauthenticated(FlowyError error) = Unauthenticated; const factory AuthState.initial() = _Initial; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index ab844448dc..2199d59562 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -28,12 +28,12 @@ class CheckboxCellBloc extends Bloc { } @freezed -abstract class CheckboxCellEvent with _$CheckboxCellEvent { +class CheckboxCellEvent with _$CheckboxCellEvent { const factory CheckboxCellEvent.initial() = _InitialCell; } @freezed -abstract class CheckboxCellState with _$CheckboxCellState { +class CheckboxCellState with _$CheckboxCellState { const factory CheckboxCellState({ required Cell? cell, }) = _CheckboxCellState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index dcb0461165..071757fdeb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -28,12 +28,12 @@ class DateCellBloc extends Bloc { } @freezed -abstract class DateCellEvent with _$DateCellEvent { +class DateCellEvent with _$DateCellEvent { const factory DateCellEvent.initial() = _InitialCell; } @freezed -abstract class DateCellState with _$DateCellState { +class DateCellState with _$DateCellState { const factory DateCellState({ required Cell? cell, }) = _DateCellState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index caa91fa408..e368c32c35 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -28,12 +28,12 @@ class NumberCellBloc extends Bloc { } @freezed -abstract class NumberCellEvent with _$NumberCellEvent { +class NumberCellEvent with _$NumberCellEvent { const factory NumberCellEvent.initial() = _InitialCell; } @freezed -abstract class NumberCellState with _$NumberCellState { +class NumberCellState with _$NumberCellState { const factory NumberCellState({ required Cell? cell, }) = _NumberCellState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 7f21a84fff..1a94d4ce69 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -28,12 +28,12 @@ class SelectionCellBloc extends Bloc { } @freezed -abstract class SelectionCellEvent with _$SelectionCellEvent { +class SelectionCellEvent with _$SelectionCellEvent { const factory SelectionCellEvent.initial() = _InitialCell; } @freezed -abstract class SelectionCellState with _$SelectionCellState { +class SelectionCellState with _$SelectionCellState { const factory SelectionCellState({ required Cell? cell, }) = _SelectionCellState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 407cde3d2c..d999ea774d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -31,13 +31,13 @@ class TextCellBloc extends Bloc { } @freezed -abstract class TextCellEvent with _$TextCellEvent { +class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; const factory TextCellEvent.updateText(String text) = _UpdateText; } @freezed -abstract class TextCellState with _$TextCellState { +class TextCellState with _$TextCellState { const factory TextCellState({ required String content, }) = _TextCellState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart index 9f70646415..aa0d47e5d6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart @@ -1,5 +1,6 @@ import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -16,9 +17,9 @@ class CreateFieldBloc extends Bloc { (event, emit) async { await event.map( initial: (_InitialField value) async { - final result = await service.getDefaultField(); + final result = await service.getEditFieldContext(FieldType.RichText); result.fold( - (field) => emit(state.copyWith(field: Some(field))), + (editContext) => emit(state.copyWith(editContext: Some(editContext))), (err) => Log.error(err), ); }, @@ -46,11 +47,11 @@ class CreateFieldEvent with _$CreateFieldEvent { class CreateFieldState with _$CreateFieldState { const factory CreateFieldState({ required String errorText, - required Option field, + required Option editContext, }) = _CreateFieldState; factory CreateFieldState.initial() => CreateFieldState( - field: none(), + editContext: none(), errorText: '', ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart index 0944bdd1bb..75a0a7c9bc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart @@ -9,7 +9,8 @@ part 'edit_field_bloc.freezed.dart'; class EditFieldBloc extends Bloc { final FieldService service; - EditFieldBloc({required Field field, required this.service}) : super(EditFieldState.initial(field)) { + EditFieldBloc({required Field field, required this.service}) + : super(EditFieldState.initial(EditFieldContext.create()..gridField = field)) { on( (event, emit) async { await event.map( @@ -43,12 +44,12 @@ class EditFieldEvent with _$EditFieldEvent { @freezed class EditFieldState with _$EditFieldState { const factory EditFieldState({ - required Field field, + required EditFieldContext editContext, required String errorText, }) = _EditFieldState; - factory EditFieldState.initial(Field field) => EditFieldState( - field: field, + factory EditFieldState.initial(EditFieldContext editContext) => EditFieldState( + editContext: editContext, errorText: '', ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index f63d8d5d5f..e3dfdf3ce9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -5,6 +5,7 @@ import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart'; class FieldService { @@ -12,9 +13,12 @@ class FieldService { FieldService({required this.gridId}); - Future> getDefaultField() { - final payload = GridId.create()..value = gridId; - return GridEventCreateDefaultField(payload).send(); + Future> getEditFieldContext(FieldType fieldType) { + final payload = CreateEditFieldContextParams.create() + ..gridId = gridId + ..fieldType = fieldType; + + return GridEventCreateEditFieldContext(payload).send(); } Future> createTextField( @@ -24,7 +28,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return createField(gridId, field, typeOptionData, startFieldId); + return createField(field, typeOptionData, startFieldId); } Future> createSingleSelectField( @@ -34,7 +38,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return createField(gridId, field, typeOptionData, startFieldId); + return createField(field, typeOptionData, startFieldId); } Future> createMultiSelectField( @@ -44,7 +48,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return createField(gridId, field, typeOptionData, startFieldId); + return createField(field, typeOptionData, startFieldId); } Future> createNumberField( @@ -54,7 +58,7 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return createField(gridId, field, typeOptionData, startFieldId); + return createField(field, typeOptionData, startFieldId); } Future> createDateField( @@ -64,11 +68,10 @@ class FieldService { String? startFieldId, ) { final typeOptionData = typeOption.writeToBuffer(); - return createField(gridId, field, typeOptionData, startFieldId); + return createField(field, typeOptionData, startFieldId); } Future> createField( - String gridId, Field field, Uint8List? typeOptionData, String? startFieldId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart new file mode 100644 index 0000000000..a6042c52e3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart @@ -0,0 +1,61 @@ +import 'dart:typed_data'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'switch_field_type_bloc.freezed.dart'; + +class SwitchFieldTypeBloc extends Bloc { + SwitchFieldTypeBloc(EditFieldContext editContext) : super(SwitchFieldTypeState.initial(editContext)) { + on( + (event, emit) async { + await event.map( + toFieldType: (_ToFieldType value) async { + final fieldService = FieldService(gridId: state.gridId); + final result = await fieldService.getEditFieldContext(value.fieldType); + result.fold( + (newEditContext) { + emit( + state.copyWith( + field: newEditContext.gridField, + typeOptionData: Uint8List.fromList(newEditContext.typeOptionData), + ), + ); + }, + (err) => Log.error(err), + ); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class SwitchFieldTypeEvent with _$SwitchFieldTypeEvent { + const factory SwitchFieldTypeEvent.toFieldType(FieldType fieldType) = _ToFieldType; +} + +@freezed +class SwitchFieldTypeState with _$SwitchFieldTypeState { + const factory SwitchFieldTypeState({ + required String gridId, + required Field field, + required Uint8List typeOptionData, + }) = _SwitchFieldTypeState; + + factory SwitchFieldTypeState.initial(EditFieldContext editContext) => SwitchFieldTypeState( + gridId: editContext.gridId, + field: editContext.gridField, + typeOptionData: Uint8List.fromList(editContext.typeOptionData), + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart new file mode 100644 index 0000000000..78b22b078b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -0,0 +1,39 @@ +import 'dart:typed_data'; + +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'date_bloc.freezed.dart'; + +class DateTypeOptionBloc extends Bloc { + DateTypeOptionBloc() : super(DateTypeOptionState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class DateTypeOptionEvent with _$DateTypeOptionEvent { + const factory DateTypeOptionEvent.initial(Uint8List? typeOptionData) = _InitialField; +} + +@freezed +class DateTypeOptionState with _$DateTypeOptionState { + const factory DateTypeOptionState() = _DateTypeOptionState; + + factory DateTypeOptionState.initial() => DateTypeOptionState(); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart new file mode 100644 index 0000000000..21043f003b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart @@ -0,0 +1,39 @@ +import 'dart:typed_data'; + +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'number_bloc.freezed.dart'; + +class NumberTypeOptionBloc extends Bloc { + NumberTypeOptionBloc() : super(NumberTypeOptionState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class NumberTypeOptionEvent with _$NumberTypeOptionEvent { + const factory NumberTypeOptionEvent.initial(Uint8List? typeOptionData) = _InitialField; +} + +@freezed +class NumberTypeOptionState with _$NumberTypeOptionState { + const factory NumberTypeOptionState() = _NumberTypeOptionState; + + factory NumberTypeOptionState.initial() => NumberTypeOptionState(); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart new file mode 100644 index 0000000000..ac6d3fb6d4 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart @@ -0,0 +1,39 @@ +import 'dart:typed_data'; + +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'selection_bloc.freezed.dart'; + +class SelectionTypeOptionBloc extends Bloc { + SelectionTypeOptionBloc() : super(SelectionTypeOptionState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class SelectionTypeOptionEvent with _$SelectionTypeOptionEvent { + const factory SelectionTypeOptionEvent.initial(Uint8List? typeOptionData) = _InitialField; +} + +@freezed +class SelectionTypeOptionState with _$SelectionTypeOptionState { + const factory SelectionTypeOptionState() = _SelectionTypeOptionState; + + factory SelectionTypeOptionState.initial() => SelectionTypeOptionState(); +} 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 63a2a19ec7..ea090a086a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -124,7 +124,7 @@ class GridBloc extends Bloc { } @freezed -abstract class GridEvent with _$GridEvent { +class GridEvent with _$GridEvent { const factory GridEvent.initial() = InitialGrid; const factory GridEvent.rename(String gridId, String name) = _Rename; const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; @@ -135,7 +135,7 @@ abstract class GridEvent with _$GridEvent { } @freezed -abstract class GridState with _$GridState { +class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, required List fields, diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index a1c60d7efb..38135f75f6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -3,10 +3,20 @@ export 'row/row_bloc.dart'; export 'row/row_service.dart'; export 'grid_service.dart'; export 'data.dart'; + +// Field export 'field/field_service.dart'; export 'field/grid_header_bloc.dart'; export 'field/edit_field_bloc.dart'; export 'field/create_field_bloc.dart'; +export 'field/switch_field_type_bloc.dart'; + +// Field Type Option +export 'field/type_option/date_bloc.dart'; +export 'field/type_option/number_bloc.dart'; +export 'field/type_option/selection_bloc.dart'; + +// Cell export 'cell_bloc/text_cell_bloc.dart'; export 'cell_bloc/number_cell_bloc.dart'; export 'cell_bloc/selection_cell_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index a30bea39ee..b7e4f40c5d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -88,7 +88,7 @@ class RowBloc extends Bloc { } @freezed -abstract class RowEvent with _$RowEvent { +class RowEvent with _$RowEvent { const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.activeRow() = _ActiveRow; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 7aa412589e..d612110ecb 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -22,7 +22,7 @@ Widget buildGridCell(GridCellData cellData) { case FieldType.SingleSelect: return SingleSelectCell(cellContext: cellData); default: - return const BlankCell(); + throw UnimplementedError; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index 0b8e2c3eac..8ac70b3741 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -37,8 +37,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate { @override void didRemove() async { - await _createFieldBloc.close(); - // TODO: implement didRemove + _createFieldBloc.add(const CreateFieldEvent.done()); } } @@ -52,16 +51,16 @@ class _CreateFieldPannelWidget extends StatelessWidget { value: createFieldBloc, child: BlocBuilder( builder: (context, state) { - return state.field.fold( + return state.editContext.fold( () => const SizedBox(), - (field) => ListView( + (editContext) => ListView( shrinkWrap: true, children: [ const FlowyText.medium("Edit property", fontSize: 12), const VSpace(10), - _FieldNameTextField(field), + _FieldNameTextField(editContext.gridField), const VSpace(10), - _FieldTypeSwitcher(field), + _FieldTypeSwitcher(editContext), const VSpace(10), ], ), @@ -73,19 +72,12 @@ class _CreateFieldPannelWidget extends StatelessWidget { } class _FieldTypeSwitcher extends StatelessWidget { - final Field field; - const _FieldTypeSwitcher(this.field, {Key? key}) : super(key: key); + final EditFieldContext editContext; + const _FieldTypeSwitcher(this.editContext, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return FieldTypeSwitcher( - field: field, - onSelectField: _switchToFieldType, - ); - } - - void _switchToFieldType(FieldType fieldType) { - throw UnimplementedError(); + return FieldTypeSwitcher(editContext: editContext); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index c199553cc6..ed26ecbd64 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -59,15 +59,11 @@ class _FieldTypeSwitcher extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - final field = context.read().state.field; - return FieldTypeSwitcher(field: field, onSelectField: _switchToFieldType); + final editContext = context.read().state.editContext; + return FieldTypeSwitcher(editContext: editContext); }, ); } - - void _switchToFieldType(FieldType fieldType) { - throw UnimplementedError(); - } } class _FieldNameTextField extends StatelessWidget { @@ -76,10 +72,10 @@ class _FieldNameTextField extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( - buildWhen: ((previous, current) => previous.field.name == current.field.name), + buildWhen: ((previous, current) => previous.editContext.gridField.name == current.editContext.gridField.name), builder: (context, state) { return FieldNameTextField( - name: state.field.name, + name: state.editContext.gridField.name, errorText: state.errorText, onNameChanged: (newName) { context.read().add(EditFieldEvent.updateFieldName(newName)); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart index 49f0513099..80cb327379 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_name_input.dart @@ -19,7 +19,7 @@ class FieldNameTextField extends StatelessWidget { final theme = context.watch(); return RoundedInputField( height: 36, - style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), + style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500), initialValue: name, normalBorderColor: theme.shader4, errorBorderColor: theme.red, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index 61b7c49b2d..df6ecf0d6a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -1,3 +1,7 @@ +import 'dart:typed_data'; + +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -5,34 +9,217 @@ import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; typedef SelectFieldCallback = void Function(FieldType); class FieldTypeSwitcher extends StatelessWidget { - final Field field; - final SelectFieldCallback onSelectField; + final EditFieldContext editContext; + const FieldTypeSwitcher({ - required this.field, - required this.onSelectField, + required this.editContext, Key? key, }) : super(key: key); @override Widget build(BuildContext context) { - final theme = context.watch(); + return BlocProvider( + create: (context) => getIt(param1: editContext), + child: BlocBuilder( + builder: (context, state) { + List children = [ + _switchFieldTypeButton(context, state.field), + ]; + final builder = _makeTypeOptionBuild( + state.field.fieldType, + state.typeOptionData, + ); + + final typeOptionWidget = builder.customWidget; + if (typeOptionWidget != null) { + children.add(typeOptionWidget); + } + + return ListView( + shrinkWrap: true, + children: children, + ); + }, + ), + ); + } + + Widget _switchFieldTypeButton(BuildContext context, Field field) { + final theme = context.watch(); return SizedBox( height: 36, child: FlowyButton( text: FlowyText.medium(field.fieldType.title(), fontSize: 12), padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), hoverColor: theme.hover, - onTap: () => FieldTypeList.show(context, onSelectField), + onTap: () => FieldTypeList.show(context, (fieldType) { + context.read().add(SwitchFieldTypeEvent.toFieldType(fieldType)); + }), leftIcon: svg(field.fieldType.iconName(), color: theme.iconColor), rightIcon: svg("grid/more", color: theme.iconColor), ), ); } } + +abstract class TypeOptionBuilder { + Uint8List? get typeOptionData; + Widget? get customWidget; +} + +abstract class TypeOptionWidget extends StatelessWidget { + const TypeOptionWidget({Key? key}) : super(key: key); +} + +TypeOptionBuilder _makeTypeOptionBuild(FieldType fieldType, Uint8List typeOptionData) { + switch (fieldType) { + case FieldType.Checkbox: + return CheckboxTypeOptionBuilder(typeOptionData); + case FieldType.DateTime: + return DateTypeOptionBuilder(typeOptionData); + case FieldType.MultiSelect: + return MultiSelectTypeOptionBuilder(typeOptionData); + case FieldType.Number: + return NumberTypeOptionBuilder(typeOptionData); + case FieldType.RichText: + return RichTextTypeOptionBuilder(typeOptionData); + case FieldType.SingleSelect: + return SingleSelectTypeOptionBuilder(typeOptionData); + default: + throw UnimplementedError; + } +} + +class RichTextTypeOptionBuilder extends TypeOptionBuilder { + RichTextTypeOption typeOption; + + RichTextTypeOptionBuilder(Uint8List typeOptionData) : typeOption = RichTextTypeOption.fromBuffer(typeOptionData); + + @override + Uint8List? get typeOptionData => typeOption.writeToBuffer(); + + @override + Widget? get customWidget => null; +} + +class NumberTypeOptionBuilder extends TypeOptionBuilder { + NumberTypeOption typeOption; + + NumberTypeOptionBuilder(Uint8List typeOptionData) : typeOption = NumberTypeOption.fromBuffer(typeOptionData); + + @override + Uint8List? get typeOptionData => typeOption.writeToBuffer(); + + @override + Widget? get customWidget => const NumberTypeOptionWidget(); +} + +class NumberTypeOptionWidget extends TypeOptionWidget { + const NumberTypeOptionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(), + child: Container(), + ); + } +} + +class DateTypeOptionBuilder extends TypeOptionBuilder { + DateTypeOption typeOption; + + DateTypeOptionBuilder(Uint8List typeOptionData) : typeOption = DateTypeOption.fromBuffer(typeOptionData); + + @override + Uint8List? get typeOptionData => typeOption.writeToBuffer(); + + @override + Widget? get customWidget => const DateTypeOptionWidget(); +} + +class DateTypeOptionWidget extends TypeOptionWidget { + const DateTypeOptionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(), + child: Container(), + ); + } +} + +class CheckboxTypeOptionBuilder extends TypeOptionBuilder { + CheckboxTypeOption typeOption; + + CheckboxTypeOptionBuilder(Uint8List typeOptionData) : typeOption = CheckboxTypeOption.fromBuffer(typeOptionData); + + @override + Uint8List? get typeOptionData => throw UnimplementedError(); + + @override + Widget? get customWidget => null; +} + +class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { + SingleSelectTypeOption typeOption; + + SingleSelectTypeOptionBuilder(Uint8List typeOptionData) + : typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData); + + @override + Uint8List? get typeOptionData => typeOption.writeToBuffer(); + + @override + Widget? get customWidget => const SingleSelectTypeOptionWidget(); +} + +class SingleSelectTypeOptionWidget extends TypeOptionWidget { + const SingleSelectTypeOptionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(), + child: Container(), + ); + } +} + +class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { + MultiSelectTypeOption typeOption; + + MultiSelectTypeOptionBuilder(Uint8List typeOptionData) + : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); + + @override + Uint8List? get typeOptionData => typeOption.writeToBuffer(); + + @override + Widget? get customWidget => const MultiSelectTypeOptionWidget(); +} + +class MultiSelectTypeOptionWidget extends TypeOptionWidget { + const MultiSelectTypeOptionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(), + child: Container(), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index 25ff77494d..25481fce09 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -104,8 +104,7 @@ extension FieldTypeListExtension on FieldType { case FieldType.SingleSelect: return "grid/field/single_select"; default: - assert(false, "Unsupport field type"); - return "grid/field/text"; + throw UnimplementedError; } } @@ -124,8 +123,7 @@ extension FieldTypeListExtension on FieldType { case FieldType.SingleSelect: return LocaleKeys.grid_field_singleSelectFieldName.tr(); default: - assert(false, "Unsupport field type"); - return LocaleKeys.grid_field_textFieldName.tr(); + throw UnimplementedError; } } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart index bee123d248..b1f18b6695 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart @@ -21,7 +21,7 @@ class OverlayContainer extends StatelessWidget { type: MaterialType.transparency, child: Container( padding: padding, - decoration: FlowyDecoration.decoration(theme.surface, theme.shadowColor.withOpacity(0.1)), + decoration: FlowyDecoration.decoration(theme.surface, theme.shadowColor.withOpacity(0.15)), constraints: constraints, child: child, ), 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 c5f7002138..88f404d4f6 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 @@ -86,18 +86,18 @@ class GridEventCreateField { } } -class GridEventCreateDefaultField { - GridId request; - GridEventCreateDefaultField(this.request); +class GridEventCreateEditFieldContext { + CreateEditFieldContextParams request; + GridEventCreateEditFieldContext(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() - ..event = GridEvent.CreateDefaultField.toString() + ..event = GridEvent.CreateEditFieldContext.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (okBytes) => left(Field.fromBuffer(okBytes)), + (okBytes) => left(EditFieldContext.fromBuffer(okBytes)), (errBytes) => right(FlowyError.fromBuffer(errBytes)), )); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index ce247ef7d6..4ea447d729 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 @@ -252,6 +252,144 @@ class FieldOrder extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); } +class CreateEditFieldContextParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateEditFieldContextParams', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..e<$0.FieldType>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..hasRequiredFields = false + ; + + CreateEditFieldContextParams._() : super(); + factory CreateEditFieldContextParams({ + $core.String? gridId, + $0.FieldType? fieldType, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + return _result; + } + factory CreateEditFieldContextParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateEditFieldContextParams.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') + CreateEditFieldContextParams clone() => CreateEditFieldContextParams()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateEditFieldContextParams copyWith(void Function(CreateEditFieldContextParams) updates) => super.copyWith((message) => updates(message as CreateEditFieldContextParams)) as CreateEditFieldContextParams; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateEditFieldContextParams create() => CreateEditFieldContextParams._(); + CreateEditFieldContextParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateEditFieldContextParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateEditFieldContextParams? _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) + $0.FieldType get fieldType => $_getN(1); + @$pb.TagNumber(2) + set fieldType($0.FieldType v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasFieldType() => $_has(1); + @$pb.TagNumber(2) + void clearFieldType() => clearField(2); +} + +class EditFieldContext extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'EditFieldContext', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridField', subBuilder: Field.create) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + EditFieldContext._() : super(); + factory EditFieldContext({ + $core.String? gridId, + Field? gridField, + $core.List<$core.int>? typeOptionData, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (gridField != null) { + _result.gridField = gridField; + } + if (typeOptionData != null) { + _result.typeOptionData = typeOptionData; + } + return _result; + } + factory EditFieldContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory EditFieldContext.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') + EditFieldContext clone() => EditFieldContext()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + EditFieldContext copyWith(void Function(EditFieldContext) updates) => super.copyWith((message) => updates(message as EditFieldContext)) as EditFieldContext; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static EditFieldContext create() => EditFieldContext._(); + EditFieldContext createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static EditFieldContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static EditFieldContext? _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) + Field get gridField => $_getN(1); + @$pb.TagNumber(2) + set gridField(Field v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasGridField() => $_has(1); + @$pb.TagNumber(2) + void clearGridField() => clearField(2); + @$pb.TagNumber(2) + Field ensureGridField() => $_ensure(1); + + @$pb.TagNumber(3) + $core.List<$core.int> get typeOptionData => $_getN(2); + @$pb.TagNumber(3) + set typeOptionData($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasTypeOptionData() => $_has(2); + @$pb.TagNumber(3) + void clearTypeOptionData() => clearField(3); +} + 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) 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 adb25af959..a7dc3255c8 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 @@ -46,6 +46,29 @@ const FieldOrder$json = const { /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); +@$core.Deprecated('Use createEditFieldContextParamsDescriptor instead') +const CreateEditFieldContextParams$json = const { + '1': 'CreateEditFieldContextParams', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_type', '3': 2, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + ], +}; + +/// Descriptor for `CreateEditFieldContextParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createEditFieldContextParamsDescriptor = $convert.base64Decode('ChxDcmVhdGVFZGl0RmllbGRDb250ZXh0UGFyYW1zEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIpCgpmaWVsZF90eXBlGAIgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGU='); +@$core.Deprecated('Use editFieldContextDescriptor instead') +const EditFieldContext$json = const { + '1': 'EditFieldContext', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'grid_field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'gridField'}, + const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'}, + ], +}; + +/// Descriptor for `EditFieldContext`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List editFieldContextDescriptor = $convert.base64Decode('ChBFZGl0RmllbGRDb250ZXh0EhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIlCgpncmlkX2ZpZWxkGAIgASgLMgYuRmllbGRSCWdyaWRGaWVsZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ=='); @$core.Deprecated('Use repeatedFieldDescriptor instead') const RepeatedField$json = const { '1': 'RepeatedField', 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 7007f1f6c8..74cb74e42e 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 @@ -15,7 +15,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); - static const GridEvent CreateDefaultField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultField'); + static const GridEvent CreateEditFieldContext = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); @@ -26,7 +26,7 @@ class GridEvent extends $pb.ProtobufEnum { GetFields, UpdateField, CreateField, - CreateDefaultField, + CreateEditFieldContext, CreateRow, GetRow, UpdateCell, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 1d94f8227a..386cdd5bcb 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 @@ -17,7 +17,7 @@ const GridEvent$json = const { const {'1': 'GetFields', '2': 10}, const {'1': 'UpdateField', '2': 11}, const {'1': 'CreateField', '2': 12}, - const {'1': 'CreateDefaultField', '2': 13}, + const {'1': 'CreateEditFieldContext', '2': 13}, const {'1': 'CreateRow', '2': 21}, const {'1': 'GetRow', '2': 22}, const {'1': 'UpdateCell', '2': 30}, @@ -25,4 +25,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEhYKEkNyZWF0ZURlZmF1bHRGaWVsZBANEg0KCUNyZWF0ZVJvdxAVEgoKBkdldFJvdxAWEg4KClVwZGF0ZUNlbGwQHg=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEhoKFkNyZWF0ZUVkaXRGaWVsZENvbnRleHQQDRINCglDcmVhdGVSb3cQFRIKCgZHZXRSb3cQFhIOCgpVcGRhdGVDZWxsEB4='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 39d6bf2e95..fb21efdd37 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,8 +1,9 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateFieldPayload, CreateRowPayload, Field, FieldChangeset, Grid, GridId, QueryFieldPayload, - QueryGridBlocksPayload, QueryRowPayload, RepeatedField, RepeatedGridBlock, Row, + CellMetaChangeset, CreateEditFieldContextParams, CreateFieldPayload, CreateRowPayload, EditFieldContext, Field, + FieldChangeset, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, QueryRowPayload, RepeatedField, + RepeatedGridBlock, Row, }; use flowy_grid_data_model::parser::{ CreateFieldParams, CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams, @@ -72,14 +73,23 @@ pub(crate) async fn create_field_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn create_default_field_handler( - data: Data, +pub(crate) async fn create_field_edit_context_handler( + data: Data, manager: AppData>, -) -> DataResult { - let grid_id: GridId = data.into_inner(); - let editor = manager.get_grid_editor(grid_id.as_ref())?; - let field = editor.make_default_field().await?; - data_result(field) +) -> DataResult { + let params: CreateEditFieldContextParams = data.into_inner(); + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let field_meta = editor.make_field_meta_from_ty(¶ms.field_type).await?; + let type_option_data = field_meta.type_option.as_bytes().to_vec(); + let field: Field = field_meta.into(); + + let edit_context = EditFieldContext { + grid_id: params.grid_id, + grid_field: field, + type_option_data, + }; + + data_result(edit_context) } #[tracing::instrument(level = "debug", skip(data, manager), err)] diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 8c08d547ff..b9fb842151 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -13,7 +13,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) - .event(GridEvent::CreateDefaultField, create_default_field_handler) + .event(GridEvent::CreateEditFieldContext, create_field_edit_context_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); @@ -39,8 +39,8 @@ pub enum GridEvent { #[event(input = "CreateFieldPayload")] CreateField = 12, - #[event(input = "GridId", output = "Field")] - CreateDefaultField = 13, + #[event(input = "CreateEditFieldContextParams", output = "EditFieldContext")] + CreateEditFieldContext = 13, #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 21, 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 4e0008c7a0..fb0e652790 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 @@ -30,7 +30,7 @@ pub enum GridEvent { GetFields = 10, UpdateField = 11, CreateField = 12, - CreateDefaultField = 13, + CreateEditFieldContext = 13, CreateRow = 21, GetRow = 22, UpdateCell = 30, @@ -48,7 +48,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 10 => ::std::option::Option::Some(GridEvent::GetFields), 11 => ::std::option::Option::Some(GridEvent::UpdateField), 12 => ::std::option::Option::Some(GridEvent::CreateField), - 13 => ::std::option::Option::Some(GridEvent::CreateDefaultField), + 13 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), 21 => ::std::option::Option::Some(GridEvent::CreateRow), 22 => ::std::option::Option::Some(GridEvent::GetRow), 30 => ::std::option::Option::Some(GridEvent::UpdateCell), @@ -63,7 +63,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetFields, GridEvent::UpdateField, GridEvent::CreateField, - GridEvent::CreateDefaultField, + GridEvent::CreateEditFieldContext, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, @@ -95,11 +95,11 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xa3\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xa7\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ - \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x16\n\x12Cr\ - eateDefaultField\x10\r\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\x10\ - \x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\ + \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x1a\n\x16Cr\ + eateEditFieldContext\x10\r\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\ + \x10\x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index 894b2a111a..f6a07a0119 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 @@ -6,7 +6,7 @@ enum GridEvent { GetFields = 10; UpdateField = 11; CreateField = 12; - CreateDefaultField = 13; + CreateEditFieldContext = 13; CreateRow = 21; GetRow = 22; UpdateCell = 30; 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 d81b96a1ad..3089836220 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -62,11 +62,10 @@ impl ClientGridEditor { Ok(()) } - pub async fn make_default_field(&self) -> FlowyResult { - let field_type = FieldType::default(); + pub async fn make_field_meta_from_ty(&self, field_type: &FieldType) -> FlowyResult { let name = format!("Property {}", self.pad.read().await.fields().len()); let field_meta = FieldBuilder::from_field_type(&field_type).name(&name).build(); - Ok(field_meta.into()) + Ok(field_meta) } pub async fn contain_field(&self, field_id: &str) -> bool { 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 c421dcac64..6d17fbca0f 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -67,6 +67,27 @@ impl std::convert::From for Field { } } +#[derive(Debug, Default, ProtoBuf)] +pub struct CreateEditFieldContextParams { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_type: FieldType, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct EditFieldContext { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub grid_field: Field, + + #[pb(index = 3)] + pub type_option_data: Vec, +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedField { #[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 5a8dced09b..a6afa46d9a 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 @@ -818,6 +818,454 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct CreateEditFieldContextParams { + // message fields + pub grid_id: ::std::string::String, + pub field_type: super::meta::FieldType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateEditFieldContextParams { + fn default() -> &'a CreateEditFieldContextParams { + ::default_instance() + } +} + +impl CreateEditFieldContextParams { + pub fn new() -> CreateEditFieldContextParams { + ::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()) + } + + // .FieldType field_type = 2; + + + pub fn get_field_type(&self) -> super::meta::FieldType { + self.field_type + } + pub fn clear_field_type(&mut self) { + self.field_type = super::meta::FieldType::RichText; + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: super::meta::FieldType) { + self.field_type = v; + } +} + +impl ::protobuf::Message for CreateEditFieldContextParams { + 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_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if self.field_type != super::meta::FieldType::RichText { + my_size += ::protobuf::rt::enum_size(2, self.field_type); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if self.field_type != super::meta::FieldType::RichText { + os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + 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() -> CreateEditFieldContextParams { + CreateEditFieldContextParams::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: &CreateEditFieldContextParams| { &m.grid_id }, + |m: &mut CreateEditFieldContextParams| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "field_type", + |m: &CreateEditFieldContextParams| { &m.field_type }, + |m: &mut CreateEditFieldContextParams| { &mut m.field_type }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateEditFieldContextParams", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateEditFieldContextParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateEditFieldContextParams::new) + } +} + +impl ::protobuf::Clear for CreateEditFieldContextParams { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_type = super::meta::FieldType::RichText; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateEditFieldContextParams { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateEditFieldContextParams { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct EditFieldContext { + // message fields + pub grid_id: ::std::string::String, + pub grid_field: ::protobuf::SingularPtrField, + pub type_option_data: ::std::vec::Vec, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a EditFieldContext { + fn default() -> &'a EditFieldContext { + ::default_instance() + } +} + +impl EditFieldContext { + pub fn new() -> EditFieldContext { + ::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()) + } + + // .Field grid_field = 2; + + + pub fn get_grid_field(&self) -> &Field { + self.grid_field.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_grid_field(&mut self) { + self.grid_field.clear(); + } + + pub fn has_grid_field(&self) -> bool { + self.grid_field.is_some() + } + + // Param is passed by value, moved + pub fn set_grid_field(&mut self, v: Field) { + self.grid_field = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_field(&mut self) -> &mut Field { + if self.grid_field.is_none() { + self.grid_field.set_default(); + } + self.grid_field.as_mut().unwrap() + } + + // Take field + pub fn take_grid_field(&mut self) -> Field { + self.grid_field.take().unwrap_or_else(|| Field::new()) + } + + // bytes type_option_data = 3; + + + pub fn get_type_option_data(&self) -> &[u8] { + &self.type_option_data + } + pub fn clear_type_option_data(&mut self) { + self.type_option_data.clear(); + } + + // Param is passed by value, moved + pub fn set_type_option_data(&mut self, v: ::std::vec::Vec) { + self.type_option_data = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec { + &mut self.type_option_data + } + + // Take field + pub fn take_type_option_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.type_option_data, ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for EditFieldContext { + fn is_initialized(&self) -> bool { + for v in &self.grid_field { + 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.grid_field)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.type_option_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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if let Some(ref v) = self.grid_field.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.type_option_data.is_empty() { + my_size += ::protobuf::rt::bytes_size(3, &self.type_option_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.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.grid_field.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 !self.type_option_data.is_empty() { + os.write_bytes(3, &self.type_option_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() -> EditFieldContext { + EditFieldContext::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: &EditFieldContext| { &m.grid_id }, + |m: &mut EditFieldContext| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_field", + |m: &EditFieldContext| { &m.grid_field }, + |m: &mut EditFieldContext| { &mut m.grid_field }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "type_option_data", + |m: &EditFieldContext| { &m.type_option_data }, + |m: &mut EditFieldContext| { &mut m.type_option_data }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "EditFieldContext", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static EditFieldContext { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(EditFieldContext::new) + } +} + +impl ::protobuf::Clear for EditFieldContext { + fn clear(&mut self) { + self.grid_id.clear(); + self.grid_field.clear(); + self.type_option_data.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for EditFieldContext { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for EditFieldContext { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedField { // message fields @@ -4418,21 +4866,26 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\ \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\ - \x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Re\ - peatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\ - \x05items\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ - wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06he\ - ight\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\ - \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\ - \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ - \x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03k\ - ey\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\ - \x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ - \x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\ - \x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockO\ - rder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBloc\ - k\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"b\n\x1cCreateEditFiel\ + dContextParams\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12)\n\ + \nfield_type\x18\x02\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditF\ + ieldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ng\ + rid_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_opt\ + ion_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ + \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ + edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ + ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ + t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ + \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ + \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ + \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ + .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ + \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ + items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\ + \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ \x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b\ 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 b1252fc72e..ec109f580f 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 @@ -18,6 +18,15 @@ message Field { message FieldOrder { string field_id = 1; } +message CreateEditFieldContextParams { + string grid_id = 1; + FieldType field_type = 2; +} +message EditFieldContext { + string grid_id = 1; + Field grid_field = 2; + bytes type_option_data = 3; +} message RepeatedField { repeated Field items = 1; } From 28948e567c1eee815e4250cd240ef9094e999f14 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 25 Mar 2022 20:55:56 +0800 Subject: [PATCH 061/179] fix: serde type option data --- .../flowy-grid-data-model/meta.pb.dart | 16 +-- .../flowy-grid-data-model/meta.pbjson.dart | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 9 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 2 +- frontend/rust-lib/flowy-grid/src/macros.rs | 34 ++++- .../src/services/field/field_builder.rs | 81 ++++++++---- .../type_options/checkbox_type_option.rs | 14 +- .../field/type_options/date_type_option.rs | 14 +- .../field/type_options/number_type_option.rs | 13 +- .../type_options/selection_type_option.rs | 25 +++- .../field/type_options/text_type_option.rs | 14 +- .../flowy-grid/src/services/grid_editor.rs | 35 +++-- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- .../src/entities/meta.rs | 4 +- .../src/protobuf/model/meta.rs | 120 +++++++++--------- .../src/protobuf/proto/meta.proto | 2 +- .../src/client_grid/grid_meta_pad.rs | 36 ++---- 18 files changed, 264 insertions(+), 165 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 24f3409349..d76dac347c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -215,7 +215,7 @@ class FieldMeta extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOption') + ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionJson') ..hasRequiredFields = false ; @@ -228,7 +228,7 @@ class FieldMeta extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - $core.String? typeOption, + $core.String? typeOptionJson, }) { final _result = create(); if (id != null) { @@ -252,8 +252,8 @@ class FieldMeta extends $pb.GeneratedMessage { if (width != null) { _result.width = width; } - if (typeOption != null) { - _result.typeOption = typeOption; + if (typeOptionJson != null) { + _result.typeOptionJson = typeOptionJson; } return _result; } @@ -342,13 +342,13 @@ class FieldMeta extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - $core.String get typeOption => $_getSZ(7); + $core.String get typeOptionJson => $_getSZ(7); @$pb.TagNumber(8) - set typeOption($core.String v) { $_setString(7, v); } + set typeOptionJson($core.String v) { $_setString(7, v); } @$pb.TagNumber(8) - $core.bool hasTypeOption() => $_has(7); + $core.bool hasTypeOptionJson() => $_has(7); @$pb.TagNumber(8) - void clearTypeOption() => clearField(8); + void clearTypeOptionJson() => clearField(8); } enum FieldChangeset_OneOfName { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index cf69a051b1..cec14f8af9 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -69,12 +69,12 @@ const FieldMeta$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_option', '3': 8, '4': 1, '5': 9, '10': 'typeOption'}, + const {'1': 'type_option_json', '3': 8, '4': 1, '5': 9, '10': 'typeOptionJson'}, ], }; /// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSHwoLdHlwZV9vcHRpb24YCCABKAlSCnR5cGVPcHRpb24='); +final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSKAoQdHlwZV9vcHRpb25fanNvbhgIIAEoCVIOdHlwZU9wdGlvbkpzb24='); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index fb21efdd37..84a526c164 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,4 +1,5 @@ use crate::manager::GridManager; +use crate::services::field::type_option_data_from_str; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ CellMetaChangeset, CreateEditFieldContextParams, CreateFieldPayload, CreateRowPayload, EditFieldContext, Field, @@ -73,22 +74,20 @@ pub(crate) async fn create_field_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn create_field_edit_context_handler( +pub(crate) async fn create_edit_field_context_handler( data: Data, manager: AppData>, ) -> DataResult { let params: CreateEditFieldContextParams = data.into_inner(); let editor = manager.get_grid_editor(¶ms.grid_id)?; - let field_meta = editor.make_field_meta_from_ty(¶ms.field_type).await?; - let type_option_data = field_meta.type_option.as_bytes().to_vec(); + let field_meta = editor.default_field_meta(¶ms.field_type).await?; + let type_option_data = type_option_data_from_str(&field_meta.type_option_json, &field_meta.field_type); let field: Field = field_meta.into(); - let edit_context = EditFieldContext { grid_id: params.grid_id, grid_field: field, type_option_data, }; - data_result(edit_context) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index b9fb842151..054e1f2328 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -13,7 +13,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) - .event(GridEvent::CreateEditFieldContext, create_field_edit_context_handler) + .event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index b4a9cf1531..f2970fb96c 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -1,3 +1,29 @@ +#[macro_export] +macro_rules! impl_into_box_type_option_builder { + ($target: ident) => { + impl std::convert::Into for $target { + fn into(self) -> Box { + Box::new(self) + } + } + }; +} + +macro_rules! impl_from_json_str_and_from_bytes { + ($target: ident,$type_option: ident) => { + impl $target { + pub fn from_json_str(s: &str) -> $target { + $target($type_option::from(s)) + } + + pub fn from_bytes(bytes: Bytes) -> $target { + let type_option = $type_option::try_from(bytes).unwrap_or($type_option::default()); + $target(type_option) + } + } + }; +} + #[macro_export] macro_rules! impl_from_and_to_type_option { ($target: ident, $field_type:expr) => { @@ -11,7 +37,13 @@ macro_rules! impl_from_field_type_option { ($target: ident) => { impl std::convert::From<&FieldMeta> for $target { fn from(field_meta: &FieldMeta) -> $target { - match serde_json::from_str(&field_meta.type_option) { + $target::from(field_meta.type_option_json.as_str()) + } + } + + impl std::convert::From<&str> for $target { + fn from(type_option_str: &str) -> $target { + match serde_json::from_str(type_option_str) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 64f5e40ee4..474a97e885 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,22 +1,26 @@ use crate::services::field::type_options::*; +use bytes::Bytes; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; pub struct FieldBuilder { field_meta: FieldMeta, - type_option_builder: Box, + type_option_builder: Box, } +pub type BoxTypeOptionBuilder = Box; + impl FieldBuilder { - pub fn new(type_option_builder: T) -> Self { + pub fn new>(type_option_builder: T) -> Self { + let type_option_builder = type_option_builder.into(); let field_meta = FieldMeta::new("", "", type_option_builder.field_type()); Self { field_meta, - type_option_builder: Box::new(type_option_builder), + type_option_builder, } } pub fn from_field_type(field_type: &FieldType) -> Self { - let type_option_builder = type_option_builder_from_type(field_type); + let type_option_builder = default_type_option_builder_from_type(field_type); Self::new(type_option_builder) } @@ -45,39 +49,62 @@ impl FieldBuilder { self } - pub fn build(mut self) -> FieldMeta { + pub fn build(self) -> FieldMeta { debug_assert_eq!(self.field_meta.field_type, self.type_option_builder.field_type()); - let type_options = self.type_option_builder.build(); - self.field_meta.type_option = type_options; - self.field_meta + let mut field_meta = self.field_meta; + let type_option_json = self.type_option_builder.build_type_option_str(); + field_meta.type_option_json = type_option_json; + field_meta } } -pub trait TypeOptionsBuilder { +pub trait TypeOptionBuilder { fn field_type(&self) -> FieldType; - fn build(&self) -> String; + fn build_type_option_str(&self) -> String; + fn build_type_option_data(&self) -> Bytes; } -pub fn type_option_builder_from_type(field_type: &FieldType) -> Box { +pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box { + let s: String = match field_type { + FieldType::RichText => RichTextTypeOption::default().into(), + FieldType::Number => NumberTypeOption::default().into(), + FieldType::DateTime => DateTypeOption::default().into(), + FieldType::SingleSelect => SingleSelectTypeOption::default().into(), + FieldType::MultiSelect => MultiSelectTypeOption::default().into(), + FieldType::Checkbox => CheckboxTypeOption::default().into(), + }; + + type_option_builder_from_json_str(&s, field_type) +} + +pub fn type_option_builder_from_json_str(s: &str, field_type: &FieldType) -> Box { match field_type { - FieldType::RichText => Box::new(RichTextTypeOptionBuilder::default()), - FieldType::Number => Box::new(NumberTypeOptionBuilder::default()), - FieldType::DateTime => Box::new(DateTypeOptionBuilder::default()), - FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::default()), - FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::default()), - FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::default()), + FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_json_str(s)), + FieldType::Number => Box::new(NumberTypeOptionBuilder::from_json_str(s)), + FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_json_str(s)), + FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_json_str(s)), + FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_json_str(s)), + FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_json_str(s)), } } -impl TypeOptionsBuilder for Box -where - T: TypeOptionsBuilder + ?Sized, -{ - fn field_type(&self) -> FieldType { - (**self).field_type() - } - - fn build(&self) -> String { - (**self).build() +pub fn type_option_builder_from_bytes(bytes: Bytes, field_type: &FieldType) -> Box { + match field_type { + FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_bytes(bytes)), + FieldType::Number => Box::new(NumberTypeOptionBuilder::from_bytes(bytes)), + FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_bytes(bytes)), + FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_bytes(bytes)), + FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_bytes(bytes)), + FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_bytes(bytes)), } } + +pub fn type_option_data_from_str(s: &str, field_type: &FieldType) -> Vec { + let builder = type_option_builder_from_json_str(s, field_type); + builder.build_type_option_data().to_vec() +} + +pub fn type_option_json_str_from_bytes(bytes: Vec, field_type: &FieldType) -> String { + let builder = type_option_builder_from_bytes(Bytes::from(bytes), field_type); + builder.build_type_option_str() +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 08ae9f79c8..e150b9f96d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,6 +1,7 @@ use crate::impl_from_and_to_type_option; -use crate::services::field::TypeOptionsBuilder; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; +use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; @@ -8,6 +9,9 @@ use serde::{Deserialize, Serialize}; #[derive(Default)] pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption); +impl_into_box_type_option_builder!(CheckboxTypeOptionBuilder); +impl_from_json_str_and_from_bytes!(CheckboxTypeOptionBuilder, CheckboxTypeOption); + impl CheckboxTypeOptionBuilder { pub fn set_selected(mut self, is_selected: bool) -> Self { self.0.is_selected = is_selected; @@ -15,14 +19,18 @@ impl CheckboxTypeOptionBuilder { } } -impl TypeOptionsBuilder for CheckboxTypeOptionBuilder { +impl TypeOptionBuilder for CheckboxTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build(&self) -> String { + fn build_type_option_str(&self) -> String { self.0.clone().into() } + + fn build_type_option_data(&self) -> Bytes { + self.0.clone().try_into().unwrap() + } } #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 20d94c8ca8..4e2a50ea33 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,5 +1,6 @@ use crate::impl_from_and_to_type_option; use crate::services::row::CellDataSerde; +use bytes::Bytes; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; @@ -8,7 +9,7 @@ use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; -use crate::services::field::TypeOptionsBuilder; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use strum_macros::EnumIter; // Date @@ -64,6 +65,9 @@ impl CellDataSerde for DateTypeOption { #[derive(Default)] pub struct DateTypeOptionBuilder(DateTypeOption); +impl_into_box_type_option_builder!(DateTypeOptionBuilder); +impl_from_json_str_and_from_bytes!(DateTypeOptionBuilder, DateTypeOption); + impl DateTypeOptionBuilder { pub fn date_format(mut self, date_format: DateFormat) -> Self { self.0.date_format = date_format; @@ -75,14 +79,18 @@ impl DateTypeOptionBuilder { self } } -impl TypeOptionsBuilder for DateTypeOptionBuilder { +impl TypeOptionBuilder for DateTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build(&self) -> String { + fn build_type_option_str(&self) -> String { self.0.clone().into() } + + fn build_type_option_data(&self) -> Bytes { + self.0.clone().try_into().unwrap() + } } #[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 5fa74285df..f3b546fcc9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -9,7 +9,8 @@ use rust_decimal::Decimal; use rusty_money::iso::{Currency, CNY, EUR, USD}; use serde::{Deserialize, Serialize}; -use crate::services::field::TypeOptionsBuilder; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; +use bytes::Bytes; use std::str::FromStr; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -20,6 +21,8 @@ lazy_static! { #[derive(Default)] pub struct NumberTypeOptionBuilder(NumberTypeOption); +impl_into_box_type_option_builder!(NumberTypeOptionBuilder); +impl_from_json_str_and_from_bytes!(NumberTypeOptionBuilder, NumberTypeOption); impl NumberTypeOptionBuilder { pub fn name(mut self, name: &str) -> Self { @@ -43,14 +46,18 @@ impl NumberTypeOptionBuilder { } } -impl TypeOptionsBuilder for NumberTypeOptionBuilder { +impl TypeOptionBuilder for NumberTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build(&self) -> String { + fn build_type_option_str(&self) -> String { self.0.clone().into() } + + fn build_type_option_data(&self) -> Bytes { + self.0.clone().try_into().unwrap() + } } // Number diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 5c4a3c5141..84feb9e051 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,7 +1,8 @@ use crate::impl_from_and_to_type_option; -use crate::services::field::TypeOptionsBuilder; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; use crate::services::util::*; +use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; @@ -34,6 +35,8 @@ impl CellDataSerde for SingleSelectTypeOption { #[derive(Default)] pub struct SingleSelectTypeOptionBuilder(SingleSelectTypeOption); +impl_into_box_type_option_builder!(SingleSelectTypeOptionBuilder); +impl_from_json_str_and_from_bytes!(SingleSelectTypeOptionBuilder, SingleSelectTypeOption); impl SingleSelectTypeOptionBuilder { pub fn option(mut self, opt: SelectOption) -> Self { @@ -41,14 +44,19 @@ impl SingleSelectTypeOptionBuilder { self } } -impl TypeOptionsBuilder for SingleSelectTypeOptionBuilder { + +impl TypeOptionBuilder for SingleSelectTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build(&self) -> String { + fn build_type_option_str(&self) -> String { self.0.clone().into() } + + fn build_type_option_data(&self) -> Bytes { + self.0.clone().try_into().unwrap() + } } // Multiple select @@ -61,6 +69,7 @@ pub struct MultiSelectTypeOption { pub disable_color: bool, } impl_from_and_to_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); + impl CellDataSerde for MultiSelectTypeOption { fn deserialize_cell_data(&self, data: String) -> String { data @@ -73,6 +82,8 @@ impl CellDataSerde for MultiSelectTypeOption { #[derive(Default)] pub struct MultiSelectTypeOptionBuilder(MultiSelectTypeOption); +impl_into_box_type_option_builder!(MultiSelectTypeOptionBuilder); +impl_from_json_str_and_from_bytes!(MultiSelectTypeOptionBuilder, MultiSelectTypeOption); impl MultiSelectTypeOptionBuilder { pub fn option(mut self, opt: SelectOption) -> Self { self.0.options.push(opt); @@ -80,14 +91,18 @@ impl MultiSelectTypeOptionBuilder { } } -impl TypeOptionsBuilder for MultiSelectTypeOptionBuilder { +impl TypeOptionBuilder for MultiSelectTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build(&self) -> String { + fn build_type_option_str(&self) -> String { self.0.clone().into() } + + fn build_type_option_data(&self) -> Bytes { + self.0.clone().try_into().unwrap() + } } fn single_select_option_id_from_data(data: String) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index dc7e0e56d0..3b2cfa051d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,7 +1,7 @@ use crate::impl_from_and_to_type_option; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; - -use crate::services::field::TypeOptionsBuilder; +use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; @@ -9,15 +9,21 @@ use serde::{Deserialize, Serialize}; #[derive(Default)] pub struct RichTextTypeOptionBuilder(RichTextTypeOption); +impl_into_box_type_option_builder!(RichTextTypeOptionBuilder); +impl_from_json_str_and_from_bytes!(RichTextTypeOptionBuilder, RichTextTypeOption); -impl TypeOptionsBuilder for RichTextTypeOptionBuilder { +impl TypeOptionBuilder for RichTextTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build(&self) -> String { + fn build_type_option_str(&self) -> String { self.0.clone().into() } + + fn build_type_option_data(&self) -> Bytes { + self.0.clone().try_into().unwrap() + } } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] 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 3089836220..6978705592 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{type_option_builder_from_type, FieldBuilder}; +use crate::services::field::{default_type_option_builder_from_type, type_option_json_str_from_bytes, FieldBuilder}; use crate::services::row::*; use bytes::Bytes; use flowy_error::{FlowyError, FlowyResult}; @@ -49,20 +49,35 @@ impl ClientGridEditor { })) } - pub async fn create_field(&self, mut params: CreateFieldParams) -> FlowyResult<()> { - if params.type_option_data.is_empty() { - params.type_option_data = type_option_builder_from_type(¶ms.field.field_type) - .build() - .as_bytes() - .to_vec(); - } + pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> { + let CreateFieldParams { + field, + type_option_data, + start_field_id, + .. + } = params; - let _ = self.modify(|grid| Ok(grid.create_field(params)?)).await?; + let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); + + let field_meta = FieldMeta { + id: field.id, + name: field.name, + desc: field.desc, + field_type: field.field_type, + frozen: field.frozen, + visibility: field.visibility, + width: field.width, + type_option_json, + }; + + let _ = self + .modify(|grid| Ok(grid.create_field(field_meta, start_field_id)?)) + .await?; let _ = self.notify_did_update_fields().await?; Ok(()) } - pub async fn make_field_meta_from_ty(&self, field_type: &FieldType) -> FlowyResult { + pub async fn default_field_meta(&self, field_type: &FieldType) -> FlowyResult { let name = format!("Property {}", self.pad.read().await.fields().len()); let field_meta = FieldBuilder::from_field_type(&field_type).name(&name).build(); Ok(field_meta) diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 4cda3a599e..5881c7ee84 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -100,7 +100,7 @@ async fn grid_update_field() { cloned_field.frozen = true; cloned_field.width = 1000; - cloned_field.type_option = single_select_type_options.into(); + cloned_field.type_option_json = single_select_type_options.into(); let scripts = vec![ CreateField { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index d622d3acbe..b2dbc2c7a9 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -268,7 +268,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { let params = CreateFieldParams { grid_id: grid_id.to_owned(), field, - type_option_data: field_meta.type_option.as_bytes().to_vec(), + type_option_data: field_meta.type_option_json.as_bytes().to_vec(), start_field_id: None, }; (params, cloned_field_meta) @@ -295,7 +295,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet let params = CreateFieldParams { grid_id: grid_id.to_owned(), field, - type_option_data: field_meta.type_option.as_bytes().to_vec(), + type_option_data: field_meta.type_option_json.as_bytes().to_vec(), start_field_id: None, }; (params, cloned_field_meta) diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 9bfc977838..24258c2d0c 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -98,7 +98,7 @@ pub struct FieldMeta { pub width: i32, #[pb(index = 8)] - pub type_option: String, + pub type_option_json: String, } impl FieldMeta { @@ -111,7 +111,7 @@ impl FieldMeta { frozen: false, visibility: true, width: DEFAULT_FIELD_WIDTH, - type_option: Default::default(), + type_option_json: Default::default(), } } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index df2c87d586..eaea731897 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -727,7 +727,7 @@ pub struct FieldMeta { pub frozen: bool, pub visibility: bool, pub width: i32, - pub type_option: ::std::string::String, + pub type_option_json: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -882,30 +882,30 @@ impl FieldMeta { self.width = v; } - // string type_option = 8; + // string type_option_json = 8; - pub fn get_type_option(&self) -> &str { - &self.type_option + pub fn get_type_option_json(&self) -> &str { + &self.type_option_json } - pub fn clear_type_option(&mut self) { - self.type_option.clear(); + pub fn clear_type_option_json(&mut self) { + self.type_option_json.clear(); } // Param is passed by value, moved - pub fn set_type_option(&mut self, v: ::std::string::String) { - self.type_option = v; + pub fn set_type_option_json(&mut self, v: ::std::string::String) { + self.type_option_json = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_type_option(&mut self) -> &mut ::std::string::String { - &mut self.type_option + pub fn mut_type_option_json(&mut self) -> &mut ::std::string::String { + &mut self.type_option_json } // Take field - pub fn take_type_option(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_option, ::std::string::String::new()) + pub fn take_type_option_json(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_option_json, ::std::string::String::new()) } } @@ -952,7 +952,7 @@ impl ::protobuf::Message for FieldMeta { self.width = tmp; }, 8 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_option)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_option_json)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -987,8 +987,8 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } - if !self.type_option.is_empty() { - my_size += ::protobuf::rt::string_size(8, &self.type_option); + if !self.type_option_json.is_empty() { + my_size += ::protobuf::rt::string_size(8, &self.type_option_json); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1017,8 +1017,8 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { os.write_int32(7, self.width)?; } - if !self.type_option.is_empty() { - os.write_string(8, &self.type_option)?; + if !self.type_option_json.is_empty() { + os.write_string(8, &self.type_option_json)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1094,9 +1094,9 @@ impl ::protobuf::Message for FieldMeta { |m: &mut FieldMeta| { &mut m.width }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_option", - |m: &FieldMeta| { &m.type_option }, - |m: &mut FieldMeta| { &mut m.type_option }, + "type_option_json", + |m: &FieldMeta| { &m.type_option_json }, + |m: &mut FieldMeta| { &mut m.type_option_json }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldMeta", @@ -1121,7 +1121,7 @@ impl ::protobuf::Clear for FieldMeta { self.frozen = false; self.visibility = false; self.width = 0; - self.type_option.clear(); + self.type_option_json.clear(); self.unknown_fields.clear(); } } @@ -3507,50 +3507,50 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\ aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\ - metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdd\x01\n\tFieldM\ + metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xe6\x01\n\tFieldM\ eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ - idth\x12\x1f\n\x0btype_option\x18\x08\x20\x01(\tR\ntypeOption\"\x96\x03\ - \n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldI\ - d\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\ - \x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\ - \x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\ - \tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\ - \x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05w\ - idth\x18\x08\x20\x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\t\ - \x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_desc\ - B\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visi\ - bilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyD\ - ata\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05valu\ - e\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\ - \x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07\ - blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.Cel\ - lByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05\ - R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\ - \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ - \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\ - \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\ - \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\ - field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ - llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ - \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ - \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChange\ - set\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_\ - id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\ - R\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bon\ - e_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\ - \x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bblock_metas\x18\x02\ - \x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fblock_meta_data\ - \x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaData*d\n\tField\ - Type\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08\ - DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSel\ - ect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + idth\x12(\n\x10type_option_json\x18\x08\x20\x01(\tR\x0etypeOptionJson\"\ + \x96\x03\n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\ + \x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\ + \x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\ + \x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTy\ + peH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06fr\ + ozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\ + \x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12#\n\x0ctype_optio\ + ns\x18\t\x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone\ + _of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one\ + _of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"8\n\ + \x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\ + \x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\ + \n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01\ + (\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.Row\ + Meta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\ + \x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibi\ + lity\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ + \x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\ + \x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06he\ + ight\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\ + \x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByField\ + IdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.C\ + ellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visib\ + ility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fiel\ + dId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMet\ + aChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\ + \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\ + \x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04data\ + B\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bfield_met\ + as\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bblock_metas\ + \x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fblock_me\ + ta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaData*d\n\ + \tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\ + \x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\ + \x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 10b1183fea..44ed367956 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -22,7 +22,7 @@ message FieldMeta { bool frozen = 5; bool visibility = 6; int32 width = 7; - string type_option = 8; + string type_option_json = 8; } message FieldChangeset { string field_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 06ecf07030..44b848a275 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -36,49 +36,31 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_field(&mut self, params: CreateFieldParams) -> CollaborateResult> { + pub fn create_field( + &mut self, + new_field_meta: FieldMeta, + start_field_id: Option, + ) -> CollaborateResult> { self.modify_grid(|grid| { - let CreateFieldParams { - field, - type_option_data, - start_field_id, - .. - } = params; - // Check if the field exists or not if grid .fields .iter() - .find(|field_meta| field_meta.id == field.id) + .find(|field_meta| field_meta.id == new_field_meta.id) .is_some() { tracing::warn!("Duplicate grid field"); return Ok(None); } - // Parse type option - let type_option = - String::from_utf8(type_option_data).map_err(|e| CollaborateError::internal().context(e))?; - - let field_meta = FieldMeta { - id: field.id, - name: field.name, - desc: field.desc, - field_type: field.field_type, - frozen: field.frozen, - visibility: field.visibility, - width: field.width, - type_option, - }; - let insert_index = match start_field_id { None => None, Some(start_field_id) => grid.fields.iter().position(|field| field.id == start_field_id), }; match insert_index { - None => grid.fields.push(field_meta), - Some(index) => grid.fields.insert(index, field_meta), + None => grid.fields.push(new_field_meta), + Some(index) => grid.fields.insert(index, new_field_meta), } Ok(Some(())) }) @@ -167,7 +149,7 @@ impl GridMetaPad { } if let Some(type_options) = changeset.type_options { - field.type_option = type_options; + field.type_option_json = type_options; is_changed = Some(()) } From 16598650ffbc688b6e3a382f7861c343c6b62054 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 26 Mar 2022 20:27:32 +0800 Subject: [PATCH 062/179] chore: lazy load cell --- .../app_flowy/lib/startup/deps_resolver.dart | 43 ++++--- .../lib/startup/tasks/app_widget.dart | 2 +- .../lib/user/application/user_listener.dart | 11 +- .../application/app/app_listener.dart | 5 +- .../grid/cell_bloc/cell_service.dart | 18 +-- .../grid/cell_bloc/checkbox_cell_bloc.dart | 9 +- .../grid/cell_bloc/date_cell_bloc.dart | 9 +- .../grid/cell_bloc/number_cell_bloc.dart | 8 +- .../grid/cell_bloc/selection_cell_bloc.dart | 8 +- .../grid/cell_bloc/text_cell_bloc.dart | 36 +++++- .../grid/field/create_field_bloc.dart | 59 +++++++-- .../application/grid/field/field_service.dart | 67 ++-------- .../grid/field/switch_field_type_bloc.dart | 18 ++- .../workspace/application/grid/grid_bloc.dart | 87 +++++++++---- .../application/grid/grid_block_service.dart | 13 +- .../application/grid/grid_listenr.dart | 7 +- .../application/grid/grid_service.dart | 20 --- .../application/grid/row/row_bloc.dart | 120 ++++++++++++------ .../application/grid/row/row_listener.dart | 50 +++++++- .../application/grid/row/row_service.dart | 28 ++-- .../application/trash/trash_listener.dart | 5 +- .../application/view/view_listener.dart | 5 +- .../workspace/workspace_listener.dart | 7 +- .../plugins/grid/src/grid_page.dart | 74 ++++++----- .../src/widgets/content/cell_builder.dart | 16 +-- .../src/widgets/content/checkbox_cell.dart | 2 +- .../grid/src/widgets/content/date_cell.dart | 2 +- .../grid/src/widgets/content/grid_row.dart | 96 +++++--------- .../grid/src/widgets/content/number_cell.dart | 2 +- .../src/widgets/content/selection_cell.dart | 12 +- .../grid/src/widgets/content/text_cell.dart | 10 +- .../widgets/header/create_field_pannel.dart | 57 +++++---- .../grid/src/widgets/header/field_editor.dart | 7 +- .../widgets/header/field_tyep_switcher.dart | 18 +-- .../grid/src/widgets/header/header.dart | 2 +- .../scrolling/styled_scrollview.dart | 12 +- frontend/rust-lib/flowy-grid/src/macros.rs | 6 +- .../src/services/block_meta_editor.rs | 5 +- .../type_options/checkbox_type_option.rs | 16 +-- .../field/type_options/date_type_option.rs | 4 +- .../field/type_options/number_type_option.rs | 44 +++---- .../type_options/selection_type_option.rs | 8 +- .../flowy-grid/src/services/grid_editor.rs | 6 +- frontend/rust-lib/flowy-grid/src/util.rs | 2 +- .../flowy-grid/tests/grid/grid_test.rs | 12 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- .../flowy-text-block/tests/editor/mod.rs | 1 + .../src/entities/grid.rs | 28 ++-- .../src/parser/id_parser.rs | 7 +- .../src/client_grid/grid_meta_pad.rs | 9 +- 50 files changed, 628 insertions(+), 469 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 56f115a22b..8293efd652 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -149,8 +149,8 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (data, _) => RowBloc( - rowService: RowService(data), - listener: RowListener(rowId: data.rowId), + rowData: data, + rowlistener: RowListener(rowId: data.rowId), ), ); @@ -174,38 +174,43 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (context, _) => TextCellBloc( - service: CellService(context), + getIt.registerFactoryParam( + (cellData, _) => TextCellBloc( + service: CellService(), + cellData: cellData, ), ); - getIt.registerFactoryParam( - (context, _) => SelectionCellBloc( - service: CellService(context), + getIt.registerFactoryParam( + (cellData, _) => SelectionCellBloc( + service: CellService(), + cellData: cellData, ), ); - getIt.registerFactoryParam( - (context, _) => NumberCellBloc( - service: CellService(context), + getIt.registerFactoryParam( + (cellData, _) => NumberCellBloc( + service: CellService(), + cellData: cellData, ), ); - getIt.registerFactoryParam( - (context, _) => DateCellBloc( - service: CellService(context), + getIt.registerFactoryParam( + (cellData, _) => DateCellBloc( + service: CellService(), + cellData: cellData, ), ); - getIt.registerFactoryParam( - (context, _) => CheckboxCellBloc( - service: CellService(context), + getIt.registerFactoryParam( + (cellData, _) => CheckboxCellBloc( + service: CellService(), + cellData: cellData, ), ); - getIt.registerFactoryParam( - (editContext, _) => SwitchFieldTypeBloc(editContext), + getIt.registerFactoryParam( + (context, _) => SwitchFieldTypeBloc(context), ); getIt.registerFactory( diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 23f4109042..78672193da 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -112,7 +112,7 @@ class ApplicationBlocObserver extends BlocObserver { // ignore: unnecessary_overrides void onTransition(Bloc bloc, Transition transition) { // Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}"); - //Log.debug("${transition.nextState}"); + Log.debug("${transition.nextState}"); super.onTransition(bloc, transition); } diff --git a/frontend/app_flowy/lib/user/application/user_listener.dart b/frontend/app_flowy/lib/user/application/user_listener.dart index 993aee60e0..5b212cc2d0 100644 --- a/frontend/app_flowy/lib/user/application/user_listener.dart +++ b/frontend/app_flowy/lib/user/application/user_listener.dart @@ -12,7 +12,6 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user/dart_notification.pb.dart' as user; import 'package:flowy_sdk/rust_stream.dart'; - typedef UserProfileUpdatedNotifierValue = Either; typedef AuthNotifierValue = Either; typedef WorkspaceUpdatedNotifierValue = Either, FlowyError>; @@ -23,8 +22,8 @@ class UserListener { final authDidChangedNotifier = PublishNotifier(); final workspaceUpdatedNotifier = PublishNotifier(); - late FolderNotificationParser _workspaceParser; - late UserNotificationParser _userParser; + FolderNotificationParser? _workspaceParser; + UserNotificationParser? _userParser; late UserProfile _user; UserListener({ required UserProfile user, @@ -36,12 +35,14 @@ class UserListener { _workspaceParser = FolderNotificationParser(id: _user.token, callback: _notificationCallback); _userParser = UserNotificationParser(id: _user.token, callback: _userNotificationCallback); _subscription = RustStreamReceiver.listen((observable) { - _workspaceParser.parse(observable); - _userParser.parse(observable); + _workspaceParser?.parse(observable); + _userParser?.parse(observable); }); } Future stop() async { + _workspaceParser = null; + _userParser = null; await _subscription?.cancel(); profileUpdatedNotifier.dispose(); authDidChangedNotifier.dispose(); diff --git a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart index 3d9bbbc65c..46b16bb080 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart @@ -17,7 +17,7 @@ class AppListener { StreamSubscription? _subscription; ViewsDidChangeCallback? _viewsChanged; AppDidUpdateCallback? _updated; - late FolderNotificationParser _parser; + FolderNotificationParser? _parser; String appId; AppListener({ @@ -28,7 +28,7 @@ class AppListener { _viewsChanged = viewsChanged; _updated = appUpdated; _parser = FolderNotificationParser(id: appId, callback: _bservableCallback); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _bservableCallback(FolderNotification ty, Either result) { @@ -61,6 +61,7 @@ class AppListener { } Future close() async { + _parser = null; await _subscription?.cancel(); _viewsChanged = null; _updated = null; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index 79b4d2cf52..e1af022d95 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,19 +1,21 @@ -import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class CellService { - final GridCellData context; + CellService(); - CellService(this.context); - - Future> updateCell({required String data}) { + Future> updateCell({ + required String gridId, + required String fieldId, + required String rowId, + required String data, + }) { final payload = CellMetaChangeset.create() - ..gridId = context.gridId - ..fieldId = context.field.id - ..rowId = context.rowId + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId ..data = data; return GridEventUpdateCell(payload).send(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 2199d59562..3e3c1b37bc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -8,10 +9,14 @@ part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { final CellService service; + // final FutureCellData cellData; CheckboxCellBloc({ required this.service, - }) : super(CheckboxCellState.initial(service.context.cell)) { + required FutureCellData cellData, + }) : super(CheckboxCellState.initial()) { + cellData.then((a) {}); + on( (event, emit) async { await event.map( @@ -38,5 +43,5 @@ class CheckboxCellState with _$CheckboxCellState { required Cell? cell, }) = _CheckboxCellState; - factory CheckboxCellState.initial(Cell? cell) => CheckboxCellState(cell: cell); + factory CheckboxCellState.initial() => const CheckboxCellState(cell: null); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index 071757fdeb..33829863dd 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -8,10 +9,12 @@ part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { final CellService service; + final FutureCellData cellData; DateCellBloc({ required this.service, - }) : super(DateCellState.initial(service.context.cell)) { + required this.cellData, + }) : super(DateCellState.initial()) { on( (event, emit) async { await event.map( @@ -35,8 +38,8 @@ class DateCellEvent with _$DateCellEvent { @freezed class DateCellState with _$DateCellState { const factory DateCellState({ - required Cell? cell, + Cell? cell, }) = _DateCellState; - factory DateCellState.initial(Cell? cell) => DateCellState(cell: cell); + factory DateCellState.initial() => const DateCellState(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index e368c32c35..6e58d24a54 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -11,7 +12,8 @@ class NumberCellBloc extends Bloc { NumberCellBloc({ required this.service, - }) : super(NumberCellState.initial(service.context.cell)) { + required FutureCellData cellData, + }) : super(NumberCellState.initial()) { on( (event, emit) async { await event.map( @@ -35,8 +37,8 @@ class NumberCellEvent with _$NumberCellEvent { @freezed class NumberCellState with _$NumberCellState { const factory NumberCellState({ - required Cell? cell, + Cell? cell, }) = _NumberCellState; - factory NumberCellState.initial(Cell? cell) => NumberCellState(cell: cell); + factory NumberCellState.initial() => const NumberCellState(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 1a94d4ce69..917e848a78 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -11,7 +12,8 @@ class SelectionCellBloc extends Bloc { SelectionCellBloc({ required this.service, - }) : super(SelectionCellState.initial(service.context.cell)) { + required FutureCellData cellData, + }) : super(SelectionCellState.initial()) { on( (event, emit) async { await event.map( @@ -35,8 +37,8 @@ class SelectionCellEvent with _$SelectionCellEvent { @freezed class SelectionCellState with _$SelectionCellState { const factory SelectionCellState({ - required Cell? cell, + Cell? cell, }) = _SelectionCellState; - factory SelectionCellState.initial(Cell? cell) => SelectionCellState(cell: cell); + factory SelectionCellState.initial() => const SelectionCellState(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index d999ea774d..73c2e8e03d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -10,20 +11,47 @@ class TextCellBloc extends Bloc { TextCellBloc({ required this.service, - }) : super(TextCellState.initial(service.context.cell?.content ?? "")) { + required FutureCellData cellData, + }) : super(TextCellState.initial()) { + cellData.then((cellData) { + if (cellData != null) { + add(TextCellEvent.didReceiveCellData(cellData)); + } + }); + on( (event, emit) async { await event.map( initial: (_InitialCell value) async {}, updateText: (_UpdateText value) { - service.updateCell(data: value.text); + updateCellContent(value.text); emit(state.copyWith(content: value.text)); }, + didReceiveCellData: (_DidReceiveCellData value) { + emit(state.copyWith( + cellData: value.cellData, + content: value.cellData.cell?.content ?? "", + )); + }, ); }, ); } + void updateCellContent(String content) { + if (state.cellData != null) { + final fieldId = state.cellData!.field.id; + final gridId = state.cellData!.gridId; + final rowId = state.cellData!.rowId; + service.updateCell( + data: content, + fieldId: fieldId, + gridId: gridId, + rowId: rowId, + ); + } + } + @override Future close() async { return super.close(); @@ -33,6 +61,7 @@ class TextCellBloc extends Bloc { @freezed class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; + const factory TextCellEvent.didReceiveCellData(GridCellData cellData) = _DidReceiveCellData; const factory TextCellEvent.updateText(String text) = _UpdateText; } @@ -40,7 +69,8 @@ class TextCellEvent with _$TextCellEvent { class TextCellState with _$TextCellState { const factory TextCellState({ required String content, + GridCellData? cellData, }) = _TextCellState; - factory TextCellState.initial(String content) => TextCellState(content: content); + factory TextCellState.initial() => const TextCellState(content: ""); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart index aa0d47e5d6..0fd0fb0a83 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; @@ -12,19 +14,22 @@ part 'create_field_bloc.freezed.dart'; class CreateFieldBloc extends Bloc { final FieldService service; - CreateFieldBloc({required this.service}) : super(CreateFieldState.initial()) { + CreateFieldBloc({required this.service}) : super(CreateFieldState.initial(service.gridId)) { on( (event, emit) async { await event.map( initial: (_InitialField value) async { - final result = await service.getEditFieldContext(FieldType.RichText); - result.fold( - (editContext) => emit(state.copyWith(editContext: Some(editContext))), - (err) => Log.error(err), - ); + await _getEditFieldContext(emit); + }, + updateName: (_UpdateName value) { + emit(state.copyWith(fieldName: value.name)); + }, + switchField: (_SwitchField value) { + emit(state.copyWith(field: Some(value.field), typeOptionData: value.typeOptionData)); + }, + done: (_Done value) async { + await _saveField(emit); }, - updateName: (_UpdateName value) {}, - done: (_Done value) {}, ); }, ); @@ -34,24 +39,54 @@ class CreateFieldBloc extends Bloc { Future close() async { return super.close(); } + + Future _saveField(Emitter emit) async { + await state.field.fold( + () async => null, + (field) async { + final result = await service.createField(field: field, typeOptionData: state.typeOptionData); + result.fold((l) => null, (r) => null); + }, + ); + } + + Future _getEditFieldContext(Emitter emit) async { + final result = await service.getEditFieldContext(FieldType.RichText); + result.fold( + (editContext) { + emit(state.copyWith( + field: Some(editContext.gridField), + typeOptionData: editContext.typeOptionData, + )); + }, + (err) => Log.error(err), + ); + } } @freezed class CreateFieldEvent with _$CreateFieldEvent { const factory CreateFieldEvent.initial() = _InitialField; - const factory CreateFieldEvent.updateName(String newName) = _UpdateName; + const factory CreateFieldEvent.updateName(String name) = _UpdateName; + const factory CreateFieldEvent.switchField(Field field, Uint8List typeOptionData) = _SwitchField; const factory CreateFieldEvent.done() = _Done; } @freezed class CreateFieldState with _$CreateFieldState { const factory CreateFieldState({ + required String fieldName, + required String gridId, required String errorText, - required Option editContext, + required Option field, + required List typeOptionData, }) = _CreateFieldState; - factory CreateFieldState.initial() => CreateFieldState( - editContext: none(), + factory CreateFieldState.initial(String gridId) => CreateFieldState( + gridId: gridId, + fieldName: '', + field: none(), errorText: '', + typeOptionData: List.empty(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index e3dfdf3ce9..f9d7ea9f09 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -21,66 +21,19 @@ class FieldService { return GridEventCreateEditFieldContext(payload).send(); } - Future> createTextField( - String gridId, - Field field, - RichTextTypeOption typeOption, + Future> createField({ + required Field field, + List? typeOptionData, String? startFieldId, - ) { - final typeOptionData = typeOption.writeToBuffer(); - return createField(field, typeOptionData, startFieldId); - } - - Future> createSingleSelectField( - String gridId, - Field field, - SingleSelectTypeOption typeOption, - String? startFieldId, - ) { - final typeOptionData = typeOption.writeToBuffer(); - return createField(field, typeOptionData, startFieldId); - } - - Future> createMultiSelectField( - String gridId, - Field field, - MultiSelectTypeOption typeOption, - String? startFieldId, - ) { - final typeOptionData = typeOption.writeToBuffer(); - return createField(field, typeOptionData, startFieldId); - } - - Future> createNumberField( - String gridId, - Field field, - NumberTypeOption typeOption, - String? startFieldId, - ) { - final typeOptionData = typeOption.writeToBuffer(); - return createField(field, typeOptionData, startFieldId); - } - - Future> createDateField( - String gridId, - Field field, - DateTypeOption typeOption, - String? startFieldId, - ) { - final typeOptionData = typeOption.writeToBuffer(); - return createField(field, typeOptionData, startFieldId); - } - - Future> createField( - Field field, - Uint8List? typeOptionData, - String? startFieldId, - ) { - final payload = CreateFieldPayload.create() + }) { + var payload = CreateFieldPayload.create() ..gridId = gridId ..field_2 = field - ..typeOptionData = typeOptionData ?? Uint8List.fromList([]) - ..startFieldId = startFieldId ?? ""; + ..typeOptionData = typeOptionData ?? []; + + if (startFieldId != null) { + payload.startFieldId = startFieldId; + } return GridEventCreateField(payload).send(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart index a6042c52e3..7f5417a396 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart @@ -10,7 +10,7 @@ import 'field_service.dart'; part 'switch_field_type_bloc.freezed.dart'; class SwitchFieldTypeBloc extends Bloc { - SwitchFieldTypeBloc(EditFieldContext editContext) : super(SwitchFieldTypeState.initial(editContext)) { + SwitchFieldTypeBloc(SwitchFieldContext editContext) : super(SwitchFieldTypeState.initial(editContext)) { on( (event, emit) async { await event.map( @@ -53,9 +53,17 @@ class SwitchFieldTypeState with _$SwitchFieldTypeState { required Uint8List typeOptionData, }) = _SwitchFieldTypeState; - factory SwitchFieldTypeState.initial(EditFieldContext editContext) => SwitchFieldTypeState( - gridId: editContext.gridId, - field: editContext.gridField, - typeOptionData: Uint8List.fromList(editContext.typeOptionData), + factory SwitchFieldTypeState.initial(SwitchFieldContext switchContext) => SwitchFieldTypeState( + gridId: switchContext.gridId, + field: switchContext.field, + typeOptionData: Uint8List.fromList(switchContext.typeOptionData), ); } + +class SwitchFieldContext { + final String gridId; + final Field field; + final List typeOptionData; + + SwitchFieldContext(this.gridId, this.field, this.typeOptionData); +} 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 ea090a086a..b155126a72 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -6,6 +6,7 @@ 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 'package:equatable/equatable.dart'; import 'grid_block_service.dart'; import 'grid_listenr.dart'; import 'grid_service.dart'; @@ -63,6 +64,20 @@ class GridBloc extends Bloc { await _loadGrid(emit); } + Future _initGridBlock(Grid grid) async { + _blockService = GridBlockService( + gridId: grid.id, + blockOrders: grid.blockOrders, + ); + + _blockService.blocksUpdateNotifier?.addPublishListener((result) { + result.fold( + (blockMap) => add(GridEvent.rowsDidUpdate(_buildRows(blockMap))), + (err) => Log.error('$err'), + ); + }); + } + Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); return Future( @@ -78,7 +93,7 @@ class GridBloc extends Bloc { return Future( () => result.fold( (fields) { - _initGridBlockService(grid); + _initGridBlock(grid); emit(state.copyWith( grid: Some(grid), fields: fields.items, @@ -90,29 +105,12 @@ class GridBloc extends Bloc { ); } - Future _initGridBlockService(Grid grid) async { - _blockService = GridBlockService( - gridId: grid.id, - blockOrders: grid.blockOrders, - ); - - _blockService.blocksUpdateNotifier.addPublishListener((result) { - result.fold( - (blockMap) => add(GridEvent.rowsDidUpdate(_buildRows(blockMap))), - (err) => Log.error('$err'), - ); - }); - - _gridListener.start(); - } - - List _buildRows(GridBlockMap blockMap) { - List rows = []; + List _buildRows(GridBlockMap blockMap) { + List rows = []; blockMap.forEach((_, GridBlock gridBlock) { rows.addAll(gridBlock.rowOrders.map( - (rowOrder) => GridRowData( + (rowOrder) => GridBlockRow( gridId: view.id, - fields: state.fields, blockId: gridBlock.id, rowId: rowOrder.rowId, height: rowOrder.height.toDouble(), @@ -130,7 +128,7 @@ class GridEvent with _$GridEvent { const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.rowsDidUpdate(List rows) = _RowsDidUpdate; + const factory GridEvent.rowsDidUpdate(List rows) = _RowsDidUpdate; const factory GridEvent.fieldsDidUpdate(List fields) = _FieldsDidUpdate; } @@ -139,7 +137,7 @@ class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, required List fields, - required List rows, + required List rows, required Option grid, }) = _GridState; @@ -156,3 +154,46 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.loading() = _Loading; const factory GridLoadingState.finish(Either successOrFail) = _Finish; } + +class GridBlockRow { + final String gridId; + final String rowId; + final String blockId; + final double height; + + const GridBlockRow({ + required this.gridId, + required this.rowId, + required this.blockId, + required this.height, + }); +} + +class GridRowData extends Equatable { + final String gridId; + final String rowId; + final String blockId; + final List fields; + final double height; + + const GridRowData({ + required this.gridId, + required this.rowId, + required this.blockId, + required this.fields, + required this.height, + }); + + factory GridRowData.fromBlockRow(GridBlockRow row, List fields) { + return GridRowData( + gridId: row.gridId, + rowId: row.rowId, + blockId: row.blockId, + fields: fields, + height: row.height, + ); + } + + @override + List get props => [rowId, fields]; +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 151b587d16..668b523c74 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -19,7 +19,7 @@ class GridBlockService { String gridId; GridBlockMap blockMap = GridBlockMap(); late GridBlockListener _blockListener; - PublishNotifier blocksUpdateNotifier = PublishNotifier(); + PublishNotifier? blocksUpdateNotifier = PublishNotifier(); GridBlockService({required this.gridId, required List blockOrders}) { _loadGridBlocks(blockOrders); @@ -36,6 +36,8 @@ class GridBlockService { Future stop() async { await _blockListener.stop(); + blocksUpdateNotifier?.dispose(); + blocksUpdateNotifier = null; } void _loadGridBlocks(List blockOrders) { @@ -49,9 +51,9 @@ class GridBlockService { for (final gridBlock in repeatedBlocks.items) { blockMap[gridBlock.id] = gridBlock; } - blocksUpdateNotifier.value = left(blockMap); + blocksUpdateNotifier?.value = left(blockMap); }, - (err) => blocksUpdateNotifier.value = right(err), + (err) => blocksUpdateNotifier?.value = right(err), ); }); } @@ -61,7 +63,7 @@ class GridBlockListener { final String gridId; PublishNotifier, FlowyError>> blockUpdateNotifier = PublishNotifier(comparable: null); StreamSubscription? _subscription; - late GridNotificationParser _parser; + GridNotificationParser? _parser; GridBlockListener({required this.gridId}); @@ -73,7 +75,7 @@ class GridBlockListener { }, ); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _handleObservableType(GridNotification ty, Either result) { @@ -91,6 +93,7 @@ class GridBlockListener { } Future stop() async { + _parser = null; await _subscription?.cancel(); blockUpdateNotifier.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart index e110491912..4afaa54601 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart @@ -13,9 +13,9 @@ import 'package:app_flowy/core/notification_helper.dart'; class GridListener { final String gridId; - PublishNotifier, FlowyError>> fieldsUpdateNotifier = PublishNotifier(comparable: null); + PublishNotifier, FlowyError>> fieldsUpdateNotifier = PublishNotifier(); StreamSubscription? _subscription; - late GridNotificationParser _parser; + GridNotificationParser? _parser; GridListener({required this.gridId}); void start() { @@ -26,7 +26,7 @@ class GridListener { }, ); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _handleObservableType(GridNotification ty, Either result) { @@ -43,6 +43,7 @@ class GridListener { } Future stop() async { + _parser = null; await _subscription?.cancel(); fieldsUpdateNotifier.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 2aafd02fba..9bb2e36e5f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,7 +3,6 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; -import 'package:equatable/equatable.dart'; class GridService { Future> openGrid({required String gridId}) async { @@ -34,22 +33,3 @@ class GridService { return GridEventGetFields(payload).send(); } } - -class GridRowData extends Equatable { - final String gridId; - final String rowId; - final String blockId; - final List fields; - final double height; - - const GridRowData({ - required this.gridId, - required this.rowId, - required this.blockId, - required this.fields, - required this.height, - }); - - @override - List get props => [rowId]; -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index b7e4f40c5d..ba6b64f602 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,4 +1,6 @@ -import 'package:app_flowy/workspace/application/grid/grid_service.dart'; +import 'dart:collection'; + +import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -6,20 +8,34 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'row_listener.dart'; import 'row_service.dart'; +import 'package:dartz/dartz.dart'; part 'row_bloc.freezed.dart'; +typedef CellDataMap = HashMap; + class RowBloc extends Bloc { final RowService rowService; - final RowListener listener; + final RowListener rowlistener; + final RowFieldListener fieldListener; - RowBloc({required this.rowService, required this.listener}) : super(RowState.initial(rowService.rowData)) { + RowBloc({required GridRowData rowData, required this.rowlistener}) + : rowService = RowService( + gridId: rowData.gridId, + blockId: rowData.blockId, + rowId: rowData.rowId, + ), + fieldListener = RowFieldListener( + gridId: rowData.gridId, + ), + super(RowState.initial(rowData)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async { - _startRowListening(); + _startListening(); await _loadRow(emit); + add(const RowEvent.didUpdateCell()); }, createRow: (_CreateRow value) { rowService.createRow(); @@ -30,6 +46,19 @@ class RowBloc extends Bloc { disactiveRow: (_DisactiveRow value) { emit(state.copyWith(active: false)); }, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + emit(state.copyWith(fields: value.fields)); + add(const RowEvent.didUpdateCell()); + }, + didUpdateCell: (_DidUpdateCell value) { + final Future cellDataMap = state.row.then( + (someRow) => someRow.fold( + () => HashMap.identity(), + (row) => _makeCellDatas(row), + ), + ); + emit(state.copyWith(cellDataMap: cellDataMap)); + }, ); }, ); @@ -37,53 +66,66 @@ class RowBloc extends Bloc { @override Future close() async { - await listener.close(); + await rowlistener.close(); + await fieldListener.close(); return super.close(); } - Future _startRowListening() async { - listener.updateRowNotifier.addPublishListener((result) { - result.fold((row) { - // - }, (err) => null); + Future _startListening() async { + rowlistener.updateRowNotifier.addPublishListener((result) { + result.fold( + (row) { + // + }, + (err) => Log.error(err), + ); }); - listener.updateCellNotifier.addPublishListener((result) { - result.fold((repeatedCvell) { - // - Log.info("$repeatedCvell"); - }, (r) => null); + rowlistener.updateCellNotifier.addPublishListener((result) { + result.fold( + (repeatedCell) { + Log.info("$repeatedCell"); + }, + (err) => Log.error(err), + ); }); - listener.start(); + fieldListener.updateFieldNotifier.addPublishListener((result) { + result.fold( + (fields) => add(RowEvent.didReceiveFieldUpdate(fields)), + (err) => Log.error(err), + ); + }); + + rowlistener.start(); + fieldListener.start(); } Future _loadRow(Emitter emit) async { - final Future> cellDatas = rowService.getRow().then((result) { + final Future> row = rowService.getRow().then((result) { return result.fold( - (row) => _makeCellDatas(row), - (e) { - Log.error(e); - return []; + (row) => Some(row), + (err) { + Log.error(err); + return none(); }, ); }); - emit(state.copyWith(cellDatas: cellDatas)); + emit(state.copyWith(row: row)); } - List _makeCellDatas(Row row) { - return rowService.rowData.fields.map((field) { - final cell = row.cellByFieldId[field.id]; - final rowData = rowService.rowData; - - return GridCellData( + CellDataMap _makeCellDatas(Row row) { + var map = CellDataMap.new(); + for (final field in state.fields) { + map[field.id] = GridCellData( rowId: row.id, - gridId: rowData.gridId, - blockId: rowData.blockId, - cell: cell, + gridId: rowService.gridId, + blockId: rowService.blockId, + cell: row.cellByFieldId[field.id], field: field, ); - }).toList(); + } + return map; } } @@ -93,21 +135,27 @@ class RowEvent with _$RowEvent { const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.activeRow() = _ActiveRow; const factory RowEvent.disactiveRow() = _DisactiveRow; + const factory RowEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; + const factory RowEvent.didUpdateCell() = _DidUpdateCell; } @freezed class RowState with _$RowState { const factory RowState({ required String rowId, - required double rowHeight, - required Future> cellDatas, required bool active, + required double rowHeight, + required List fields, + required Future> row, + required Future cellDataMap, }) = _RowState; factory RowState.initial(GridRowData data) => RowState( rowId: data.rowId, - rowHeight: data.height, - cellDatas: Future(() => []), active: false, + rowHeight: data.height, + fields: data.fields, + row: Future(() => none()), + cellDataMap: Future(() => CellDataMap.identity()), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart index 76a2ba617d..c5084f4164 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart @@ -11,13 +11,14 @@ import 'package:dartz/dartz.dart'; typedef UpdateCellNotifiedValue = Either; typedef UpdateRowNotifiedValue = Either; +typedef UpdateFieldNotifiedValue = Either, FlowyError>; class RowListener { final String rowId; - PublishNotifier updateCellNotifier = PublishNotifier(); - PublishNotifier updateRowNotifier = PublishNotifier(); + PublishNotifier updateCellNotifier = PublishNotifier(); + PublishNotifier updateRowNotifier = PublishNotifier(); StreamSubscription? _subscription; - late GridNotificationParser _parser; + GridNotificationParser? _parser; RowListener({required this.rowId}); @@ -29,7 +30,7 @@ class RowListener { }, ); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _handleObservableType(GridNotification ty, Either result) { @@ -40,15 +41,54 @@ class RowListener { (error) => updateCellNotifier.value = right(error), ); break; - default: break; } } Future close() async { + _parser = null; await _subscription?.cancel(); updateCellNotifier.dispose(); updateRowNotifier.dispose(); } } + +class RowFieldListener { + final String gridId; + PublishNotifier updateFieldNotifier = PublishNotifier(); + StreamSubscription? _subscription; + GridNotificationParser? _parser; + + RowFieldListener({required this.gridId}); + + void start() { + _parser = GridNotificationParser( + id: gridId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.DidUpdateFields: + result.fold( + (payload) => updateFieldNotifier.value = left(RepeatedField.fromBuffer(payload).items), + (error) => updateFieldNotifier.value = right(error), + ); + break; + default: + break; + } + } + + Future close() async { + _parser = null; + await _subscription?.cancel(); + updateFieldNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 6819a9a40e..7c77c0de64 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,45 +1,51 @@ import 'package:dartz/dartz.dart'; +import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; - class RowService { - final GridRowData rowData; + final String gridId; + final String rowId; + final String blockId; - RowService(this.rowData); + RowService({required this.gridId, required this.rowId, required this.blockId}); Future> createRow() { CreateRowPayload payload = CreateRowPayload.create() - ..gridId = rowData.gridId - ..startRowId = rowData.rowId; + ..gridId = gridId + ..startRowId = rowId; return GridEventCreateRow(payload).send(); } Future> getRow() { QueryRowPayload payload = QueryRowPayload.create() - ..gridId = rowData.gridId - ..blockId = rowData.blockId - ..rowId = rowData.rowId; + ..gridId = gridId + ..blockId = blockId + ..rowId = rowId; return GridEventGetRow(payload).send(); } } -class GridCellData { +typedef FutureCellData = Future; + +class GridCellData extends Equatable { final String gridId; final String rowId; final String blockId; final Field field; final Cell? cell; - GridCellData({ + const GridCellData({ required this.rowId, required this.gridId, required this.blockId, required this.field, required this.cell, }); + + @override + List get props => [cell, field]; } diff --git a/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart b/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart index dd0b1f58aa..36dc982466 100644 --- a/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart @@ -13,12 +13,12 @@ typedef TrashUpdatedCallback = void Function(Either, FlowyError> tra class TrashListener { StreamSubscription? _subscription; TrashUpdatedCallback? _trashUpdated; - late FolderNotificationParser _parser; + FolderNotificationParser? _parser; void start({TrashUpdatedCallback? trashUpdated}) { _trashUpdated = trashUpdated; _parser = FolderNotificationParser(callback: _bservableCallback); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _bservableCallback(FolderNotification ty, Either result) { @@ -40,6 +40,7 @@ class TrashListener { } Future close() async { + _parser = null; await _subscription?.cancel(); _trashUpdated = null; } diff --git a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart index f400124805..ee27d55139 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart @@ -18,7 +18,7 @@ class ViewListener { PublishNotifier updatedNotifier = PublishNotifier(); PublishNotifier deletedNotifier = PublishNotifier(); PublishNotifier restoredNotifier = PublishNotifier(); - late FolderNotificationParser _parser; + FolderNotificationParser? _parser; View view; ViewListener({ @@ -33,7 +33,7 @@ class ViewListener { }, ); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _handleObservableType(FolderNotification ty, Either result) { @@ -62,6 +62,7 @@ class ViewListener { } Future close() async { + _parser = null; await _subscription?.cancel(); updatedNotifier.dispose(); deletedNotifier.dispose(); diff --git a/frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart b/frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart index e5959d1562..9ac51e36f8 100644 --- a/frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart @@ -12,7 +12,6 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart'; import 'package:flowy_sdk/rust_stream.dart'; - typedef WorkspaceAppsChangedCallback = void Function(Either, FlowyError> appsOrFail); typedef WorkspaceUpdatedCallback = void Function(String name, String desc); @@ -31,12 +30,11 @@ class WorkspaceListener { } } - class WorkspaceListenerService { StreamSubscription? _subscription; WorkspaceAppsChangedCallback? _appsChanged; WorkspaceUpdatedCallback? _update; - late FolderNotificationParser _parser; + FolderNotificationParser? _parser; final UserProfile user; final String workspaceId; @@ -59,7 +57,7 @@ class WorkspaceListenerService { }, ); - _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } void _handleObservableType(FolderNotification ty, Either result) { @@ -91,6 +89,7 @@ class WorkspaceListenerService { } Future close() async { + _parser = null; await _subscription?.cancel(); // _appsChanged = null; // _update = null; 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 1b79a7a0b4..5cd23accc6 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,15 +1,13 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/grid_service.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:styled_widget/styled_widget.dart'; - import 'controller/grid_scroll.dart'; import 'layout/layout.dart'; import 'layout/sizes.dart'; @@ -92,16 +90,33 @@ class _FlowyGridState extends State { return const Center(child: CircularProgressIndicator.adaptive()); } - return _wrapScrollbar(state.fields, [ - _buildHeader(gridId, state.fields), - _buildRows(context), - const GridFooter(), - ]); + final child = BlocBuilder( + builder: (context, state) { + return SizedBox( + width: GridLayout.headerWidth(state.fields), + child: ScrollConfiguration( + behavior: const ScrollBehavior().copyWith(scrollbars: false), + child: CustomScrollView( + shrinkWrap: true, + physics: StyledScrollPhysics(), + controller: _scrollController.verticalController, + slivers: [ + _buildHeader(gridId), + _buildRows(context), + const GridFooter(), + ], + ), + ), + ); + }, + ); + + return _wrapScrollbar(child); }, ); } - Widget _wrapScrollbar(List fields, List children) { + Widget _wrapScrollbar(Widget child) { return ScrollbarListStack( axis: Axis.vertical, controller: _scrollController.verticalController, @@ -109,38 +124,39 @@ class _FlowyGridState extends State { child: StyledSingleChildScrollView( controller: _scrollController.horizontalController, axis: Axis.horizontal, - child: SizedBox( - width: GridLayout.headerWidth(fields), - child: ScrollConfiguration( - behavior: const ScrollBehavior().copyWith(scrollbars: false), - child: CustomScrollView( - physics: StyledScrollPhysics(), - controller: _scrollController.verticalController, - slivers: [...children], - ), - ), - ), + child: child, ), - ).padding(right: 0, top: GridSize.headerHeight, bottom: GridSize.scrollBarSize); + ); } - Widget _buildHeader(String gridId, List fields) { - return SliverPersistentHeader( - delegate: GridHeaderDelegate(gridId: gridId, fields: fields), - floating: true, - pinned: true, + Widget _buildHeader(String gridId) { + return BlocBuilder( + buildWhen: (previous, current) => previous.fields.length != current.fields.length, + builder: (context, state) { + return SliverPersistentHeader( + delegate: GridHeaderDelegate(gridId: gridId, fields: state.fields), + floating: true, + pinned: true, + ); + }, ); } Widget _buildRows(BuildContext context) { return BlocBuilder( - buildWhen: (previous, current) => previous.rows.length != current.rows.length, + buildWhen: (previous, current) { + final rowChanged = previous.rows.length != current.rows.length; + // final fieldChanged = previous.fields.length != current.fields.length; + return rowChanged; + }, builder: (context, state) { return SliverList( delegate: SliverChildBuilderDelegate( (context, index) { - final rowData = context.read().state.rows[index]; - return GridRowWidget(data: rowData); + final blockRow = context.read().state.rows[index]; + final fields = context.read().state.fields; + final rowData = GridRowData.fromBlockRow(blockRow, fields); + return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)); }, childCount: context.read().state.rows.length, addRepaintBoundaries: true, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index d612110ecb..fc9eb9b80b 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -7,20 +7,20 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(GridCellData cellData) { - switch (cellData.field.fieldType) { +Widget buildGridCell(FieldType fieldType, FutureCellData cellData) { + switch (fieldType) { case FieldType.Checkbox: - return CheckboxCell(cellData: cellData); + return CheckboxCell(cellData: cellData, key: ObjectKey(cellData)); case FieldType.DateTime: - return DateCell(cellData: cellData); + return DateCell(cellData: cellData, key: ObjectKey(cellData)); case FieldType.MultiSelect: - return MultiSelectCell(cellContext: cellData); + return MultiSelectCell(cellData: cellData, key: ObjectKey(cellData)); case FieldType.Number: - return NumberCell(cellData: cellData); + return NumberCell(cellData: cellData, key: ObjectKey(cellData)); case FieldType.RichText: - return GridTextCell(cellData: cellData); + return GridTextCell(cellData: cellData, key: ObjectKey(cellData)); case FieldType.SingleSelect: - return SingleSelectCell(cellContext: cellData); + return SingleSelectCell(cellData: cellData, key: ObjectKey(cellData)); default: throw UnimplementedError; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index 2f067ab1fa..dc8f757e36 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final GridCellData cellData; + final FutureCellData cellData; const CheckboxCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index 5d69783fc5..ec1babd799 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateCell extends StatefulWidget { - final GridCellData cellData; + final FutureCellData cellData; const DateCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 3efc47d33c..735143a35a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -4,61 +4,38 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; -class GridRowWidget extends StatefulWidget { +class GridRowWidget extends StatelessWidget { final GridRowData data; - GridRowWidget({required this.data, Key? key}) : super(key: ValueKey(data.rowId)); - - @override - State createState() => _GridRowWidgetState(); -} - -class _GridRowWidgetState extends State { - late RowBloc _rowBloc; - - @override - void initState() { - _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); - super.initState(); - } + const GridRowWidget({required this.data, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return BlocProvider.value( - value: _rowBloc, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), - onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, - ), + return BlocProvider( + create: (context) => getIt(param1: data)..add(const RowEvent.initial()), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, ), ); } - - @override - Future dispose() async { - _rowBloc.close(); - super.dispose(); - } } class _RowLeading extends StatelessWidget { @@ -115,30 +92,19 @@ class _RowCells extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( - buildWhen: (previous, current) => previous.cellDatas != current.cellDatas, builder: (context, state) { - return FutureBuilder( - future: state.cellDatas, - builder: builder, - ); + return Row(children: [ + ...state.fields.map( + (field) { + final cellData = state.cellDataMap.then((fut) => fut[field.id]); + return CellContainer( + width: field.width.toDouble(), + child: buildGridCell(field.fieldType, cellData), + ); + }, + ), + ]); }, ); } - - Widget builder(context, AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.done: - List cellDatas = snapshot.data; - return Row(children: cellDatas.map(_toCell).toList()); - default: - return const SizedBox(); - } - } - - Widget _toCell(GridCellData data) { - return CellContainer( - width: data.field.width.toDouble(), - child: buildGridCell(data), - ); - } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 0402b85b12..6983cc1015 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final GridCellData cellData; + final FutureCellData cellData; const NumberCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 94891924cd..0b1b1828f3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -3,10 +3,10 @@ import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { - final GridCellData cellContext; + final FutureCellData cellData; const SingleSelectCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -19,7 +19,7 @@ class _SingleSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } @@ -37,10 +37,10 @@ class _SingleSelectCellState extends State { //---------------------------------------------------------------- class MultiSelectCell extends StatefulWidget { - final GridCellData cellContext; + final FutureCellData cellData; const MultiSelectCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -53,7 +53,7 @@ class _MultiSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index d3a9e88c2e..0a8ea79771 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -8,7 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; /// The interface of base cell. class GridTextCell extends StatefulWidget { - final GridCellData cellData; + final FutureCellData cellData; const GridTextCell({ required this.cellData, Key? key, @@ -36,9 +36,11 @@ class _GridTextCellState extends State { Widget build(BuildContext context) { return BlocProvider.value( value: _cellBloc!, - child: BlocBuilder( - buildWhen: (previous, current) { - return _controller.text != current.content; + child: BlocConsumer( + listener: (context, state) { + if (_controller.text != state.content) { + _controller.text = state.content; + } }, builder: (context, state) { return TextField( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index 8ac70b3741..6a7c6d05ef 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -1,10 +1,10 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/create_field_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/switch_field_type_bloc.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_name_input.dart'; @@ -21,7 +21,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: _CreateFieldPannelWidget(_createFieldBloc), - constraints: BoxConstraints.loose(const Size(220, 200)), + constraints: BoxConstraints.loose(const Size(220, 400)), ), identifier: identifier(), anchorContext: context, @@ -36,7 +36,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate { } @override - void didRemove() async { + void didRemove() { _createFieldBloc.add(const CreateFieldEvent.done()); } } @@ -51,16 +51,16 @@ class _CreateFieldPannelWidget extends StatelessWidget { value: createFieldBloc, child: BlocBuilder( builder: (context, state) { - return state.editContext.fold( + return state.field.fold( () => const SizedBox(), - (editContext) => ListView( + (field) => ListView( shrinkWrap: true, children: [ const FlowyText.medium("Edit property", fontSize: 12), const VSpace(10), - _FieldNameTextField(editContext.gridField), + const _FieldNameTextField(), const VSpace(10), - _FieldTypeSwitcher(editContext), + _FieldTypeSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)), const VSpace(10), ], ), @@ -72,26 +72,35 @@ class _CreateFieldPannelWidget extends StatelessWidget { } class _FieldTypeSwitcher extends StatelessWidget { - final EditFieldContext editContext; - const _FieldTypeSwitcher(this.editContext, {Key? key}) : super(key: key); + final SwitchFieldContext switchContext; + const _FieldTypeSwitcher(this.switchContext, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return FieldTypeSwitcher(editContext: editContext); - } -} - -class _FieldNameTextField extends StatelessWidget { - final Field field; - const _FieldNameTextField(this.field, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return FieldNameTextField( - name: field.name, - errorText: context.read().state.errorText, - onNameChanged: (newName) { - context.read().add(CreateFieldEvent.updateName(newName)); + return FieldTypeSwitcher( + switchContext: switchContext, + onSelected: (field, typeOptionData) { + context.read().add(CreateFieldEvent.switchField(field, typeOptionData)); + }, + ); + } +} + +class _FieldNameTextField extends StatelessWidget { + const _FieldNameTextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) => previous.fieldName != current.fieldName, + builder: (context, state) { + return FieldNameTextField( + name: state.fieldName, + errorText: context.read().state.errorText, + onNameChanged: (newName) { + context.read().add(CreateFieldEvent.updateName(newName)); + }, + ); }, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index ed26ecbd64..5362250b95 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -60,7 +60,12 @@ class _FieldTypeSwitcher extends StatelessWidget { return BlocBuilder( builder: (context, state) { final editContext = context.read().state.editContext; - return FieldTypeSwitcher(editContext: editContext); + final switchContext = SwitchFieldContext( + editContext.gridId, + editContext.gridField, + editContext.typeOptionData, + ); + return FieldTypeSwitcher(switchContext: switchContext, onSelected: (field, typeOptionData) {}); }, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index df6ecf0d6a..cd9adbd928 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -17,20 +17,22 @@ import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -typedef SelectFieldCallback = void Function(FieldType); +typedef SelectFieldCallback = void Function(Field, Uint8List); class FieldTypeSwitcher extends StatelessWidget { - final EditFieldContext editContext; + final SwitchFieldContext switchContext; + final SelectFieldCallback onSelected; const FieldTypeSwitcher({ - required this.editContext, + required this.switchContext, + required this.onSelected, Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: editContext), + create: (context) => getIt(param1: switchContext), child: BlocBuilder( builder: (context, state) { List children = [ @@ -133,7 +135,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(), - child: Container(), + child: Container(height: 30, color: Colors.green), ); } } @@ -157,7 +159,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(), - child: Container(), + child: Container(height: 80, color: Colors.red), ); } } @@ -194,7 +196,7 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(), - child: Container(), + child: Container(height: 100, color: Colors.yellow), ); } } @@ -219,7 +221,7 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(), - child: Container(), + child: Container(height: 100, color: Colors.blue), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index cfac576cd5..dbebb311b9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -20,7 +20,7 @@ class GridHeaderDelegate extends SliverPersistentHeaderDelegate { @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return GridHeader(gridId: gridId, fields: fields); + return GridHeader(gridId: gridId, fields: fields, key: ObjectKey(fields)); } @override diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart index 3df1fea4c7..ed960a1c12 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart @@ -63,13 +63,11 @@ class _StyledSingleChildScrollViewState extends State { - impl std::convert::Into for $target { - fn into(self) -> Box { - Box::new(self) + impl std::convert::From<$target> for BoxTypeOptionBuilder { + fn from(target: $target) -> BoxTypeOptionBuilder { + Box::new(target) } } }; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index d6289dc958..65e80136c3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -6,8 +6,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta, - RowMetaChangeset, RowOrder, + FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{ @@ -71,7 +70,7 @@ impl GridBlockMetaEditorManager { .insert(row_meta.id.clone(), row_meta.block_id.clone()); let editor = self.get_editor(&row_meta.block_id).await?; let row_count = editor.create_row(row_meta, start_row_id).await?; - self.notify_block_did_update_row(&block_id).await?; + self.notify_block_did_update_row(block_id).await?; Ok(row_count) } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index e150b9f96d..f6e07c831a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -69,20 +69,20 @@ fn string_to_bool(bool_str: &str) -> bool { #[cfg(test)] mod tests { - use crate::services::cell::CheckboxTypeOption; + use crate::services::field::CheckboxTypeOption; use crate::services::row::CellDataSerde; #[test] fn checkout_box_description_test() { let type_option = CheckboxTypeOption::default(); - assert_eq!(description.serialize_cell_data("true").unwrap(), "1".to_owned()); - assert_eq!(description.serialize_cell_data("1").unwrap(), "1".to_owned()); - assert_eq!(description.serialize_cell_data("yes").unwrap(), "1".to_owned()); + assert_eq!(type_option.serialize_cell_data("true").unwrap(), "1".to_owned()); + assert_eq!(type_option.serialize_cell_data("1").unwrap(), "1".to_owned()); + assert_eq!(type_option.serialize_cell_data("yes").unwrap(), "1".to_owned()); - assert_eq!(description.serialize_cell_data("false").unwrap(), "0".to_owned()); - assert_eq!(description.serialize_cell_data("no").unwrap(), "0".to_owned()); - assert_eq!(description.serialize_cell_data("123").unwrap(), "0".to_owned()); + assert_eq!(type_option.serialize_cell_data("false").unwrap(), "0".to_owned()); + assert_eq!(type_option.serialize_cell_data("no").unwrap(), "0".to_owned()); + assert_eq!(type_option.serialize_cell_data("123").unwrap(), "0".to_owned()); - assert_eq!(description.deserialize_cell_data("1".to_owned()), "1".to_owned()); + assert_eq!(type_option.deserialize_cell_data("1".to_owned()), "1".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 4e2a50ea33..dca1654b3e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -177,7 +177,7 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { - use crate::services::cell::{DateFormat, DateTypeOption, TimeFormat}; + use crate::services::field::{DateFormat, DateTypeOption, TimeFormat}; use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; @@ -267,6 +267,6 @@ mod tests { #[should_panic] fn date_description_invalid_data_test() { let type_option = DateTypeOption::default(); - description.serialize_cell_data("he").unwrap(); + type_option.serialize_cell_data("he").unwrap(); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index f3b546fcc9..67de271309 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -192,41 +192,41 @@ fn make_strip_symbol() -> Vec { #[cfg(test)] mod tests { - use crate::services::cell::{NumberFormat, NumberTypeOption}; + use crate::services::field::{NumberFormat, NumberTypeOption}; use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] fn number_description_test() { - let mut description = NumberTypeOption::default(); - assert_eq!(description.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned()); - assert_eq!(description.serialize_cell_data("$18,443").unwrap(), "18443".to_owned()); - assert_eq!(description.serialize_cell_data("€18.443").unwrap(), "18443".to_owned()); + let mut type_option = NumberTypeOption::default(); + assert_eq!(type_option.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned()); + assert_eq!(type_option.serialize_cell_data("$18,443").unwrap(), "18443".to_owned()); + assert_eq!(type_option.serialize_cell_data("€18.443").unwrap(), "18443".to_owned()); for format in NumberFormat::iter() { - description.format = format; + type_option.format = format; match format { NumberFormat::Number => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "€18.443".to_owned() ); } @@ -236,35 +236,35 @@ mod tests { #[test] fn number_description_scale_test() { - let mut description = NumberTypeOption { + let mut type_option = NumberTypeOption { scale: 1, ..Default::default() }; for format in NumberFormat::iter() { - description.format = format; + type_option.format = format; match format { NumberFormat::Number => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "$1,844.3".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "¥1,844.3".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "€1.844,3".to_owned() ); } @@ -274,35 +274,35 @@ mod tests { #[test] fn number_description_sign_test() { - let mut description = NumberTypeOption { + let mut type_option = NumberTypeOption { sign_positive: false, ..Default::default() }; for format in NumberFormat::iter() { - description.format = format; + type_option.format = format; match format { NumberFormat::Number => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "-$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "-¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data("18443".to_owned()), "-€18.443".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 84feb9e051..73dd3bd432 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -166,16 +166,16 @@ impl SelectOption { #[cfg(test)] mod tests { - use crate::services::cell::{MultiSelectDescription, SingleSelectTypeOption}; + use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption}; use crate::services::row::CellDataSerde; #[test] #[should_panic] fn selection_description_test() { let type_option = SingleSelectTypeOption::default(); - assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); + assert_eq!(type_option.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); - let type_option = MultiSelectDescription::default(); - assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + let type_option = MultiSelectTypeOption::default(); + assert_eq!(type_option.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 6978705592..6a27fdbb72 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{default_type_option_builder_from_type, type_option_json_str_from_bytes, FieldBuilder}; +use crate::services::field::{type_option_json_str_from_bytes, FieldBuilder}; use crate::services::row::*; use bytes::Bytes; use flowy_error::{FlowyError, FlowyResult}; @@ -78,8 +78,8 @@ impl ClientGridEditor { } pub async fn default_field_meta(&self, field_type: &FieldType) -> FlowyResult { - let name = format!("Property {}", self.pad.read().await.fields().len()); - let field_meta = FieldBuilder::from_field_type(&field_type).name(&name).build(); + let name = format!("Property {}", self.pad.read().await.fields().len() + 1); + let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build(); Ok(field_meta) } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 1638060f61..9cc8e078e0 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,5 +1,5 @@ use crate::services::field::*; -use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; +use flowy_grid_data_model::entities::BuildGridContext; use flowy_sync::client_grid::GridBuilder; pub fn make_default_grid() -> BuildGridContext { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 5881c7ee84..3f18e5a9c0 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -254,19 +254,19 @@ async fn grid_row_add_cells_test() { } FieldType::SingleSelect => { let type_option = SingleSelectTypeOption::from(field); - let options = description.options.first().unwrap(); - let data = description.serialize_cell_data(&options.id).unwrap(); + let options = type_option.options.first().unwrap(); + let data = type_option.serialize_cell_data(&options.id).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { let type_option = MultiSelectTypeOption::from(field); - let options = description + let options = type_option .options .iter() .map(|option| option.id.clone()) .collect::>() .join(SELECTION_IDS_SEPARATOR); - let data = description.serialize_cell_data(&options).unwrap(); + let data = type_option.serialize_cell_data(&options).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::Checkbox => { @@ -383,11 +383,11 @@ async fn grid_cell_update() { FieldType::DateTime => "123".to_string(), FieldType::SingleSelect => { let type_option = SingleSelectTypeOption::from(field_meta); - description.options.first().unwrap().id.clone() + type_option.options.first().unwrap().id.clone() } FieldType::MultiSelect => { let type_option = MultiSelectTypeOption::from(field_meta); - description.options.first().unwrap().id.clone() + type_option.options.first().unwrap().id.clone() } FieldType::Checkbox => "1".to_string(), }; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index b2dbc2c7a9..7739356531 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,8 +3,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, CreateFieldPayload, Field, FieldChangeset, FieldMeta, FieldType, - GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, + BuildGridContext, CellMetaChangeset, Field, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, + GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_grid_data_model::parser::CreateFieldParams; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; diff --git a/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs b/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs index d1c6f94380..f9ed7c72ac 100644 --- a/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs @@ -4,6 +4,7 @@ mod op_test; mod serde_test; mod undo_redo_test; +use derive_more::Display; use flowy_sync::client_document::{ClientDocument, InitialDocumentText}; use lib_ot::{ core::*, 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 6d17fbca0f..a52d507c87 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -39,20 +39,6 @@ pub struct Field { pub width: i32, } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct FieldOrder { - #[pb(index = 1)] - pub field_id: String, -} - -impl std::convert::From<&FieldMeta> for FieldOrder { - fn from(field_meta: &FieldMeta) -> Self { - Self { - field_id: field_meta.id.clone(), - } - } -} - impl std::convert::From for Field { fn from(field_meta: FieldMeta) -> Self { Self { @@ -67,6 +53,20 @@ impl std::convert::From for Field { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldOrder { + #[pb(index = 1)] + pub field_id: String, +} + +impl std::convert::From<&FieldMeta> for FieldOrder { + fn from(field_meta: &FieldMeta) -> Self { + Self { + field_id: field_meta.id.clone(), + } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct CreateEditFieldContextParams { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs b/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs index f2eb8423bb..5003ab2ce4 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs @@ -4,12 +4,11 @@ use uuid::Uuid; pub struct NotEmptyUuid(pub String); impl NotEmptyUuid { - pub fn parse(s: String) -> Result { - debug_assert!(Uuid::parse_str(&s).is_ok()); - + pub fn parse(s: String) -> Result { if s.trim().is_empty() { - return Err(()); + return Err("Input string is empty".to_owned()); } + debug_assert!(Uuid::parse_str(&s).is_ok()); Ok(Self(s)) } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 44b848a275..9375f80ed0 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -5,7 +5,7 @@ use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangeset, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, }; -use flowy_grid_data_model::parser::CreateFieldParams; + use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; @@ -43,12 +43,7 @@ impl GridMetaPad { ) -> CollaborateResult> { self.modify_grid(|grid| { // Check if the field exists or not - if grid - .fields - .iter() - .find(|field_meta| field_meta.id == new_field_meta.id) - .is_some() - { + if grid.fields.iter().any(|field_meta| field_meta.id == new_field_meta.id) { tracing::warn!("Duplicate grid field"); return Ok(None); } From b65b4796d2d3da694d2332b9220c0f59bd803369 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 26 Mar 2022 21:03:54 +0800 Subject: [PATCH 063/179] fix: add event after bloc close --- .../lib/startup/tasks/app_widget.dart | 2 +- .../grid/cell_bloc/checkbox_cell_bloc.dart | 2 - .../grid/cell_bloc/text_cell_bloc.dart | 15 ++-- .../application/grid/row/row_bloc.dart | 15 ++-- .../application/grid/row/row_service.dart | 2 +- .../src/widgets/content/cell_builder.dart | 21 +++-- .../grid/src/widgets/content/grid_row.dart | 85 ++++++++++++------- .../grid/src/widgets/content/text_cell.dart | 15 ++-- 8 files changed, 91 insertions(+), 66 deletions(-) diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 78672193da..9f5493b256 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -112,7 +112,7 @@ class ApplicationBlocObserver extends BlocObserver { // ignore: unnecessary_overrides void onTransition(Bloc bloc, Transition transition) { // Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}"); - Log.debug("${transition.nextState}"); + // Log.debug("${transition.nextState}"); super.onTransition(bloc, transition); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 3e3c1b37bc..3609f39de7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -15,8 +15,6 @@ class CheckboxCellBloc extends Bloc { required this.service, required FutureCellData cellData, }) : super(CheckboxCellState.initial()) { - cellData.then((a) {}); - on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 73c2e8e03d..985fad03be 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -12,13 +12,7 @@ class TextCellBloc extends Bloc { TextCellBloc({ required this.service, required FutureCellData cellData, - }) : super(TextCellState.initial()) { - cellData.then((cellData) { - if (cellData != null) { - add(TextCellEvent.didReceiveCellData(cellData)); - } - }); - + }) : super(TextCellState.initial(cellData)) { on( (event, emit) async { await event.map( @@ -69,8 +63,11 @@ class TextCellEvent with _$TextCellEvent { class TextCellState with _$TextCellState { const factory TextCellState({ required String content, - GridCellData? cellData, + required FutureCellData cellData, }) = _TextCellState; - factory TextCellState.initial() => const TextCellState(content: ""); + factory TextCellState.initial(FutureCellData cellData) => TextCellState( + content: cellData?.cell?.content ?? "", + cellData: cellData, + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index ba6b64f602..2bb78799f0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -50,12 +50,11 @@ class RowBloc extends Bloc { emit(state.copyWith(fields: value.fields)); add(const RowEvent.didUpdateCell()); }, - didUpdateCell: (_DidUpdateCell value) { - final Future cellDataMap = state.row.then( - (someRow) => someRow.fold( - () => HashMap.identity(), - (row) => _makeCellDatas(row), - ), + didUpdateCell: (_DidUpdateCell value) async { + final optionRow = await state.row; + final CellDataMap cellDataMap = optionRow.fold( + () => HashMap.identity(), + (row) => _makeCellDatas(row), ); emit(state.copyWith(cellDataMap: cellDataMap)); }, @@ -147,7 +146,7 @@ class RowState with _$RowState { required double rowHeight, required List fields, required Future> row, - required Future cellDataMap, + required CellDataMap? cellDataMap, }) = _RowState; factory RowState.initial(GridRowData data) => RowState( @@ -156,6 +155,6 @@ class RowState with _$RowState { rowHeight: data.height, fields: data.fields, row: Future(() => none()), - cellDataMap: Future(() => CellDataMap.identity()), + cellDataMap: null, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 7c77c0de64..d30a22b7d0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -29,7 +29,7 @@ class RowService { } } -typedef FutureCellData = Future; +typedef FutureCellData = GridCellData?; class GridCellData extends Equatable { final String gridId; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index fc9eb9b80b..856338aea4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -7,20 +8,24 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(FieldType fieldType, FutureCellData cellData) { - switch (fieldType) { +Widget buildGridCell(String rowId, Field field, FutureCellData cellData) { + if (cellData == null) { + return const SizedBox(); + } + final key = ValueKey(field.id + rowId); + switch (field.fieldType) { case FieldType.Checkbox: - return CheckboxCell(cellData: cellData, key: ObjectKey(cellData)); + return CheckboxCell(cellData: cellData, key: key); case FieldType.DateTime: - return DateCell(cellData: cellData, key: ObjectKey(cellData)); + return DateCell(cellData: cellData, key: key); case FieldType.MultiSelect: - return MultiSelectCell(cellData: cellData, key: ObjectKey(cellData)); + return MultiSelectCell(cellData: cellData, key: key); case FieldType.Number: - return NumberCell(cellData: cellData, key: ObjectKey(cellData)); + return NumberCell(cellData: cellData, key: key); case FieldType.RichText: - return GridTextCell(cellData: cellData, key: ObjectKey(cellData)); + return GridTextCell(cellData: cellData, key: key); case FieldType.SingleSelect: - return SingleSelectCell(cellData: cellData, key: ObjectKey(cellData)); + return SingleSelectCell(cellData: cellData, key: key); default: throw UnimplementedError; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 735143a35a..b8834cd213 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -4,38 +4,61 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; -class GridRowWidget extends StatelessWidget { +class GridRowWidget extends StatefulWidget { final GridRowData data; const GridRowWidget({required this.data, Key? key}) : super(key: key); + @override + State createState() => _GridRowWidgetState(); +} + +class _GridRowWidgetState extends State { + late RowBloc _rowBloc; + + @override + void initState() { + _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); + super.initState(); + } + @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: data)..add(const RowEvent.initial()), - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, + return BlocProvider.value( + value: _rowBloc, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, + ), ), ); } + + @override + Future dispose() async { + _rowBloc.close(); + super.dispose(); + } } class _RowLeading extends StatelessWidget { @@ -92,18 +115,20 @@ class _RowCells extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( + buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { - return Row(children: [ - ...state.fields.map( - (field) { - final cellData = state.cellDataMap.then((fut) => fut[field.id]); - return CellContainer( - width: field.width.toDouble(), - child: buildGridCell(field.fieldType, cellData), - ); - }, - ), - ]); + final children = state.fields + .map((field) => CellContainer( + width: field.width.toDouble(), + child: buildGridCell( + state.rowId, + field, + state.cellDataMap?[field.id], + ), + )) + .toList(); + + return Row(children: children); }, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 0a8ea79771..e8c571bded 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -22,12 +22,12 @@ class _GridTextCellState extends State { late TextEditingController _controller; Timer? _delayOperation; final _focusNode = FocusNode(); - TextCellBloc? _cellBloc; + late TextCellBloc _cellBloc; @override void initState() { _cellBloc = getIt(param1: widget.cellData); - _controller = TextEditingController(text: _cellBloc!.state.content); + _controller = TextEditingController(text: _cellBloc.state.content); _focusNode.addListener(save); super.initState(); } @@ -35,7 +35,7 @@ class _GridTextCellState extends State { @override Widget build(BuildContext context) { return BlocProvider.value( - value: _cellBloc!, + value: _cellBloc, child: BlocConsumer( listener: (context, state) { if (_controller.text != state.content) { @@ -71,8 +71,7 @@ class _GridTextCellState extends State { @override Future dispose() async { - _cellBloc?.close(); - _cellBloc = null; + _cellBloc.close(); _focusNode.removeListener(save); _focusNode.dispose(); super.dispose(); @@ -80,8 +79,10 @@ class _GridTextCellState extends State { Future save() async { _delayOperation?.cancel(); - _delayOperation = Timer(const Duration(seconds: 2), () { - _cellBloc?.add(TextCellEvent.updateText(_controller.text)); + _delayOperation = Timer(const Duration(milliseconds: 300), () { + if (_cellBloc.isClosed == false) { + _cellBloc.add(TextCellEvent.updateText(_controller.text)); + } }); // and later, before the timer goes off... } From c7bba01fe54f31e8f410a52c00aa220df950413e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 27 Mar 2022 09:35:10 +0800 Subject: [PATCH 064/179] chore: delete field --- .../grid/field/create_field_bloc.dart | 7 +- .../grid/field/edit_field_bloc.dart | 2 + .../application/grid/field/field_service.dart | 39 ++- ...eld_editor.dart => edit_field_pannel.dart} | 6 +- .../grid/src/widgets/header/header_cell.dart | 4 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../flowy-error-code/code.pbenum.dart | 6 +- .../flowy-error-code/code.pbjson.dart | 5 +- .../flowy-grid-data-model/meta.pb.dart | 116 +++---- .../flowy-grid-data-model/meta.pbjson.dart | 14 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 5 +- .../rust-lib/flowy-grid/src/event_handler.rs | 24 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- .../src/protobuf/model/event_map.rs | 16 +- .../src/protobuf/proto/event_map.proto | 3 +- .../flowy-grid/src/services/grid_editor.rs | 19 +- .../flowy-grid/tests/grid/grid_test.rs | 4 +- shared-lib/flowy-error-code/src/code.rs | 7 +- .../src/protobuf/model/code.rs | 15 +- .../src/protobuf/proto/code.proto | 3 +- .../src/entities/grid.rs | 108 ++++++ .../src/entities/meta.rs | 46 ++- .../src/parser/grid_params.rs | 112 ------ .../flowy-grid-data-model/src/parser/mod.rs | 2 - .../src/protobuf/model/meta.rs | 325 +++++++++--------- .../src/protobuf/proto/meta.proto | 4 +- .../src/client_grid/grid_meta_pad.rs | 18 +- 28 files changed, 540 insertions(+), 397 deletions(-) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{field_editor.dart => edit_field_pannel.dart} (93%) delete mode 100644 shared-lib/flowy-grid-data-model/src/parser/grid_params.rs diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart index 0fd0fb0a83..29f7187c2f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart @@ -44,7 +44,12 @@ class CreateFieldBloc extends Bloc { await state.field.fold( () async => null, (field) async { - final result = await service.createField(field: field, typeOptionData: state.typeOptionData); + field.name = state.fieldName; + + final result = await service.createField( + field: field, + typeOptionData: state.typeOptionData, + ); result.fold((l) => null, (r) => null); }, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart index 75a0a7c9bc..11dbe765fc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart @@ -21,6 +21,7 @@ class EditFieldBloc extends Bloc { hideField: (_HideField value) {}, deleteField: (_DeleteField value) {}, duplicateField: (_DuplicateField value) {}, + saveField: (_SaveField value) {}, ); }, ); @@ -39,6 +40,7 @@ class EditFieldEvent with _$EditFieldEvent { const factory EditFieldEvent.hideField() = _HideField; const factory EditFieldEvent.duplicateField() = _DuplicateField; const factory EditFieldEvent.deleteField() = _DeleteField; + const factory EditFieldEvent.saveField() = _SaveField; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index f9d7ea9f09..84566da604 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -6,7 +6,6 @@ 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:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart'; class FieldService { final String gridId; @@ -21,6 +20,44 @@ class FieldService { return GridEventCreateEditFieldContext(payload).send(); } + Future> updateField({ + required Field field, + String? name, + FieldType? fieldType, + bool? frozen, + bool? visibility, + double? width, + List? typeOptionData, + }) { + var payload = FieldChangesetPayload.create()..gridId = gridId; + + if (name != null) { + payload.name = name; + } + + if (fieldType != null) { + payload.fieldType = fieldType; + } + + if (frozen != null) { + payload.frozen = frozen; + } + + if (visibility != null) { + payload.visibility = visibility; + } + + if (width != null) { + payload.width = width.toInt(); + } + + if (typeOptionData != null) { + payload.typeOptionData = typeOptionData; + } + + return GridEventUpdateField(payload).send(); + } + Future> createField({ required Field field, List? typeOptionData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart index 5362250b95..47affb67e8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart @@ -10,12 +10,12 @@ import 'field_name_input.dart'; import 'field_operation_list.dart'; import 'field_tyep_switcher.dart'; -class FieldEditor extends StatelessWidget { +class EditFieldPannel extends StatelessWidget { final GridFieldData fieldData; - const FieldEditor({required this.fieldData, Key? key}) : super(key: key); + const EditFieldPannel({required this.fieldData, Key? key}) : super(key: key); static void show(BuildContext context, GridFieldData fieldData) { - final editor = FieldEditor(fieldData: fieldData); + final editor = EditFieldPannel(fieldData: fieldData); FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: editor, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index d6e0faff47..52e7e38d75 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -7,7 +7,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'field_editor.dart'; +import 'edit_field_pannel.dart'; class HeaderCell extends StatelessWidget { final GridFieldData fieldData; @@ -18,7 +18,7 @@ class HeaderCell extends StatelessWidget { final theme = context.watch(); final button = FlowyButton( hoverColor: theme.hover, - onTap: () => FieldEditor.show(context, fieldData), + onTap: () => EditFieldPannel.show(context, fieldData), rightIcon: svg("editor/details", color: theme.iconColor), text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), ); 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 88f404d4f6..0c3d242c37 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 @@ -86,6 +86,23 @@ class GridEventCreateField { } } +class GridEventDeleteField { + FieldOrder request; + GridEventDeleteField(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.DeleteField.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateEditFieldContext { CreateEditFieldContextParams request; GridEventCreateEditFieldContext(this.request); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index d7119ad727..307b9f86f2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -46,7 +46,8 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode BlockIdIsEmpty = ErrorCode._(420, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty'); static const ErrorCode RowIdIsEmpty = ErrorCode._(430, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); static const ErrorCode FieldIdIsEmpty = ErrorCode._(440, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldIdIsEmpty'); - static const ErrorCode TypeOptionIsEmpty = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionIsEmpty'); + static const ErrorCode FieldDoesNotExist = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldDoesNotExist'); + static const ErrorCode TypeOptionDataIsEmpty = ErrorCode._(450, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionDataIsEmpty'); static const ErrorCode InvalidData = ErrorCode._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); static const $core.List values = [ @@ -86,7 +87,8 @@ class ErrorCode extends $pb.ProtobufEnum { BlockIdIsEmpty, RowIdIsEmpty, FieldIdIsEmpty, - TypeOptionIsEmpty, + FieldDoesNotExist, + TypeOptionDataIsEmpty, InvalidData, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 41815194f2..9345118baa 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -48,10 +48,11 @@ const ErrorCode$json = const { const {'1': 'BlockIdIsEmpty', '2': 420}, const {'1': 'RowIdIsEmpty', '2': 430}, const {'1': 'FieldIdIsEmpty', '2': 440}, - const {'1': 'TypeOptionIsEmpty', '2': 441}, + const {'1': 'FieldDoesNotExist', '2': 441}, + const {'1': 'TypeOptionDataIsEmpty', '2': 450}, const {'1': 'InvalidData', '2': 500}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFUeXBlT3B0aW9uSXNFbXB0eRC5AxIQCgtJbnZhbGlkRGF0YRD0Aw=='); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFGaWVsZERvZXNOb3RFeGlzdBC5AxIaChVUeXBlT3B0aW9uRGF0YUlzRW1wdHkQwgMSEAoLSW52YWxpZERhdGEQ9AM='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index d76dac347c..bc29686021 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -351,71 +351,71 @@ class FieldMeta extends $pb.GeneratedMessage { void clearTypeOptionJson() => clearField(8); } -enum FieldChangeset_OneOfName { +enum FieldChangesetPayload_OneOfName { name, notSet } -enum FieldChangeset_OneOfDesc { +enum FieldChangesetPayload_OneOfDesc { desc, notSet } -enum FieldChangeset_OneOfFieldType { +enum FieldChangesetPayload_OneOfFieldType { fieldType, notSet } -enum FieldChangeset_OneOfFrozen { +enum FieldChangesetPayload_OneOfFrozen { frozen, notSet } -enum FieldChangeset_OneOfVisibility { +enum FieldChangesetPayload_OneOfVisibility { visibility, notSet } -enum FieldChangeset_OneOfWidth { +enum FieldChangesetPayload_OneOfWidth { width, notSet } -enum FieldChangeset_OneOfTypeOptions { - typeOptions, +enum FieldChangesetPayload_OneOfTypeOptionData { + typeOptionData, notSet } -class FieldChangeset extends $pb.GeneratedMessage { - static const $core.Map<$core.int, FieldChangeset_OneOfName> _FieldChangeset_OneOfNameByTag = { - 3 : FieldChangeset_OneOfName.name, - 0 : FieldChangeset_OneOfName.notSet +class FieldChangesetPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, FieldChangesetPayload_OneOfName> _FieldChangesetPayload_OneOfNameByTag = { + 3 : FieldChangesetPayload_OneOfName.name, + 0 : FieldChangesetPayload_OneOfName.notSet }; - static const $core.Map<$core.int, FieldChangeset_OneOfDesc> _FieldChangeset_OneOfDescByTag = { - 4 : FieldChangeset_OneOfDesc.desc, - 0 : FieldChangeset_OneOfDesc.notSet + static const $core.Map<$core.int, FieldChangesetPayload_OneOfDesc> _FieldChangesetPayload_OneOfDescByTag = { + 4 : FieldChangesetPayload_OneOfDesc.desc, + 0 : FieldChangesetPayload_OneOfDesc.notSet }; - static const $core.Map<$core.int, FieldChangeset_OneOfFieldType> _FieldChangeset_OneOfFieldTypeByTag = { - 5 : FieldChangeset_OneOfFieldType.fieldType, - 0 : FieldChangeset_OneOfFieldType.notSet + static const $core.Map<$core.int, FieldChangesetPayload_OneOfFieldType> _FieldChangesetPayload_OneOfFieldTypeByTag = { + 5 : FieldChangesetPayload_OneOfFieldType.fieldType, + 0 : FieldChangesetPayload_OneOfFieldType.notSet }; - static const $core.Map<$core.int, FieldChangeset_OneOfFrozen> _FieldChangeset_OneOfFrozenByTag = { - 6 : FieldChangeset_OneOfFrozen.frozen, - 0 : FieldChangeset_OneOfFrozen.notSet + static const $core.Map<$core.int, FieldChangesetPayload_OneOfFrozen> _FieldChangesetPayload_OneOfFrozenByTag = { + 6 : FieldChangesetPayload_OneOfFrozen.frozen, + 0 : FieldChangesetPayload_OneOfFrozen.notSet }; - static const $core.Map<$core.int, FieldChangeset_OneOfVisibility> _FieldChangeset_OneOfVisibilityByTag = { - 7 : FieldChangeset_OneOfVisibility.visibility, - 0 : FieldChangeset_OneOfVisibility.notSet + static const $core.Map<$core.int, FieldChangesetPayload_OneOfVisibility> _FieldChangesetPayload_OneOfVisibilityByTag = { + 7 : FieldChangesetPayload_OneOfVisibility.visibility, + 0 : FieldChangesetPayload_OneOfVisibility.notSet }; - static const $core.Map<$core.int, FieldChangeset_OneOfWidth> _FieldChangeset_OneOfWidthByTag = { - 8 : FieldChangeset_OneOfWidth.width, - 0 : FieldChangeset_OneOfWidth.notSet + static const $core.Map<$core.int, FieldChangesetPayload_OneOfWidth> _FieldChangesetPayload_OneOfWidthByTag = { + 8 : FieldChangesetPayload_OneOfWidth.width, + 0 : FieldChangesetPayload_OneOfWidth.notSet }; - static const $core.Map<$core.int, FieldChangeset_OneOfTypeOptions> _FieldChangeset_OneOfTypeOptionsByTag = { - 9 : FieldChangeset_OneOfTypeOptions.typeOptions, - 0 : FieldChangeset_OneOfTypeOptions.notSet + static const $core.Map<$core.int, FieldChangesetPayload_OneOfTypeOptionData> _FieldChangesetPayload_OneOfTypeOptionDataByTag = { + 9 : FieldChangesetPayload_OneOfTypeOptionData.typeOptionData, + 0 : FieldChangesetPayload_OneOfTypeOptionData.notSet }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangeset', createEmptyInstance: create) + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangesetPayload', createEmptyInstance: create) ..oo(0, [3]) ..oo(1, [4]) ..oo(2, [5]) @@ -431,12 +431,12 @@ class FieldChangeset extends $pb.GeneratedMessage { ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOS(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') + ..a<$core.List<$core.int>>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY) ..hasRequiredFields = false ; - FieldChangeset._() : super(); - factory FieldChangeset({ + FieldChangesetPayload._() : super(); + factory FieldChangesetPayload({ $core.String? fieldId, $core.String? gridId, $core.String? name, @@ -445,7 +445,7 @@ class FieldChangeset extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - $core.String? typeOptions, + $core.List<$core.int>? typeOptionData, }) { final _result = create(); if (fieldId != null) { @@ -472,52 +472,52 @@ class FieldChangeset extends $pb.GeneratedMessage { if (width != null) { _result.width = width; } - if (typeOptions != null) { - _result.typeOptions = typeOptions; + if (typeOptionData != null) { + _result.typeOptionData = typeOptionData; } return _result; } - factory FieldChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FieldChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory FieldChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldChangesetPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - FieldChangeset clone() => FieldChangeset()..mergeFromMessage(this); + FieldChangesetPayload clone() => FieldChangesetPayload()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - FieldChangeset copyWith(void Function(FieldChangeset) updates) => super.copyWith((message) => updates(message as FieldChangeset)) as FieldChangeset; // ignore: deprecated_member_use + FieldChangesetPayload copyWith(void Function(FieldChangesetPayload) updates) => super.copyWith((message) => updates(message as FieldChangesetPayload)) as FieldChangesetPayload; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static FieldChangeset create() => FieldChangeset._(); - FieldChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static FieldChangesetPayload create() => FieldChangesetPayload._(); + FieldChangesetPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static FieldChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static FieldChangeset? _defaultInstance; + static FieldChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldChangesetPayload? _defaultInstance; - FieldChangeset_OneOfName whichOneOfName() => _FieldChangeset_OneOfNameByTag[$_whichOneof(0)]!; + FieldChangesetPayload_OneOfName whichOneOfName() => _FieldChangesetPayload_OneOfNameByTag[$_whichOneof(0)]!; void clearOneOfName() => clearField($_whichOneof(0)); - FieldChangeset_OneOfDesc whichOneOfDesc() => _FieldChangeset_OneOfDescByTag[$_whichOneof(1)]!; + FieldChangesetPayload_OneOfDesc whichOneOfDesc() => _FieldChangesetPayload_OneOfDescByTag[$_whichOneof(1)]!; void clearOneOfDesc() => clearField($_whichOneof(1)); - FieldChangeset_OneOfFieldType whichOneOfFieldType() => _FieldChangeset_OneOfFieldTypeByTag[$_whichOneof(2)]!; + FieldChangesetPayload_OneOfFieldType whichOneOfFieldType() => _FieldChangesetPayload_OneOfFieldTypeByTag[$_whichOneof(2)]!; void clearOneOfFieldType() => clearField($_whichOneof(2)); - FieldChangeset_OneOfFrozen whichOneOfFrozen() => _FieldChangeset_OneOfFrozenByTag[$_whichOneof(3)]!; + FieldChangesetPayload_OneOfFrozen whichOneOfFrozen() => _FieldChangesetPayload_OneOfFrozenByTag[$_whichOneof(3)]!; void clearOneOfFrozen() => clearField($_whichOneof(3)); - FieldChangeset_OneOfVisibility whichOneOfVisibility() => _FieldChangeset_OneOfVisibilityByTag[$_whichOneof(4)]!; + FieldChangesetPayload_OneOfVisibility whichOneOfVisibility() => _FieldChangesetPayload_OneOfVisibilityByTag[$_whichOneof(4)]!; void clearOneOfVisibility() => clearField($_whichOneof(4)); - FieldChangeset_OneOfWidth whichOneOfWidth() => _FieldChangeset_OneOfWidthByTag[$_whichOneof(5)]!; + FieldChangesetPayload_OneOfWidth whichOneOfWidth() => _FieldChangesetPayload_OneOfWidthByTag[$_whichOneof(5)]!; void clearOneOfWidth() => clearField($_whichOneof(5)); - FieldChangeset_OneOfTypeOptions whichOneOfTypeOptions() => _FieldChangeset_OneOfTypeOptionsByTag[$_whichOneof(6)]!; - void clearOneOfTypeOptions() => clearField($_whichOneof(6)); + FieldChangesetPayload_OneOfTypeOptionData whichOneOfTypeOptionData() => _FieldChangesetPayload_OneOfTypeOptionDataByTag[$_whichOneof(6)]!; + void clearOneOfTypeOptionData() => clearField($_whichOneof(6)); @$pb.TagNumber(1) $core.String get fieldId => $_getSZ(0); @@ -592,13 +592,13 @@ class FieldChangeset extends $pb.GeneratedMessage { void clearWidth() => clearField(8); @$pb.TagNumber(9) - $core.String get typeOptions => $_getSZ(8); + $core.List<$core.int> get typeOptionData => $_getN(8); @$pb.TagNumber(9) - set typeOptions($core.String v) { $_setString(8, v); } + set typeOptionData($core.List<$core.int> v) { $_setBytes(8, v); } @$pb.TagNumber(9) - $core.bool hasTypeOptions() => $_has(8); + $core.bool hasTypeOptionData() => $_has(8); @$pb.TagNumber(9) - void clearTypeOptions() => clearField(9); + void clearTypeOptionData() => clearField(9); } class AnyData extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index cec14f8af9..7c690f7b1e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -75,9 +75,9 @@ const FieldMeta$json = const { /// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSKAoQdHlwZV9vcHRpb25fanNvbhgIIAEoCVIOdHlwZU9wdGlvbkpzb24='); -@$core.Deprecated('Use fieldChangesetDescriptor instead') -const FieldChangeset$json = const { - '1': 'FieldChangeset', +@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead') +const FieldChangesetPayload$json = const { + '1': 'FieldChangesetPayload', '2': const [ const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, @@ -87,7 +87,7 @@ const FieldChangeset$json = const { const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'}, - const {'1': 'type_options', '3': 9, '4': 1, '5': 9, '9': 6, '10': 'typeOptions'}, + const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'}, ], '8': const [ const {'1': 'one_of_name'}, @@ -96,12 +96,12 @@ const FieldChangeset$json = const { const {'1': 'one_of_frozen'}, const {'1': 'one_of_visibility'}, const {'1': 'one_of_width'}, - const {'1': 'one_of_type_options'}, + const {'1': 'one_of_type_option_data'}, ], }; -/// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSFAoEbmFtZRgDIAEoCUgAUgRuYW1lEhQKBGRlc2MYBCABKAlIAVIEZGVzYxIrCgpmaWVsZF90eXBlGAUgASgOMgouRmllbGRUeXBlSAJSCWZpZWxkVHlwZRIYCgZmcm96ZW4YBiABKAhIA1IGZnJvemVuEiAKCnZpc2liaWxpdHkYByABKAhIBFIKdmlzaWJpbGl0eRIWCgV3aWR0aBgIIAEoBUgFUgV3aWR0aBIjCgx0eXBlX29wdGlvbnMYCSABKAlIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); +/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ=='); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', 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 74cb74e42e..755b1c1ed1 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 @@ -15,7 +15,8 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); - static const GridEvent CreateEditFieldContext = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); + static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField'); + static const GridEvent CreateEditFieldContext = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); @@ -26,6 +27,7 @@ class GridEvent extends $pb.ProtobufEnum { GetFields, UpdateField, CreateField, + DeleteField, CreateEditFieldContext, CreateRow, GetRow, 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 386cdd5bcb..9441a03bea 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 @@ -17,7 +17,8 @@ const GridEvent$json = const { const {'1': 'GetFields', '2': 10}, const {'1': 'UpdateField', '2': 11}, const {'1': 'CreateField', '2': 12}, - const {'1': 'CreateEditFieldContext', '2': 13}, + const {'1': 'DeleteField', '2': 13}, + const {'1': 'CreateEditFieldContext', '2': 14}, const {'1': 'CreateRow', '2': 21}, const {'1': 'GetRow', '2': 22}, const {'1': 'UpdateCell', '2': 30}, @@ -25,4 +26,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEhoKFkNyZWF0ZUVkaXRGaWVsZENvbnRleHQQDRINCglDcmVhdGVSb3cQFRIKCgZHZXRSb3cQFhIOCgpVcGRhdGVDZWxsEB4='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SGgoWQ3JlYXRlRWRpdEZpZWxkQ29udGV4dBAOEg0KCUNyZWF0ZVJvdxAVEgoKBkdldFJvdxAWEg4KClVwZGF0ZUNlbGwQHg=='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 84a526c164..e16c761cb2 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,14 +1,7 @@ use crate::manager::GridManager; use crate::services::field::type_option_data_from_str; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateEditFieldContextParams, CreateFieldPayload, CreateRowPayload, EditFieldContext, Field, - FieldChangeset, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, QueryRowPayload, RepeatedField, - RepeatedGridBlock, Row, -}; -use flowy_grid_data_model::parser::{ - CreateFieldParams, CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams, -}; +use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -53,10 +46,10 @@ pub(crate) async fn get_fields_handler( #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn update_field_handler( - data: Data, + data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let changeset: FieldChangeset = data.into_inner(); + let changeset: FieldChangesetParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(&changeset.grid_id)?; let _ = editor.update_field(changeset).await?; Ok(()) @@ -73,6 +66,17 @@ pub(crate) async fn create_field_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn delete_field_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let field_order: FieldOrder = data.into_inner(); + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.delete_field(&field_order.field_id).await?; + Ok(()) +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_edit_field_context_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 054e1f2328..9819f2142e 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -13,6 +13,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) + .event(GridEvent::DeleteField, create_field_handler) .event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) @@ -39,8 +40,11 @@ pub enum GridEvent { #[event(input = "CreateFieldPayload")] CreateField = 12, + #[event(input = "FieldOrder")] + DeleteField = 13, + #[event(input = "CreateEditFieldContextParams", output = "EditFieldContext")] - CreateEditFieldContext = 13, + CreateEditFieldContext = 14, #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 21, 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 fb0e652790..dfa0f30b74 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 @@ -30,7 +30,8 @@ pub enum GridEvent { GetFields = 10, UpdateField = 11, CreateField = 12, - CreateEditFieldContext = 13, + DeleteField = 13, + CreateEditFieldContext = 14, CreateRow = 21, GetRow = 22, UpdateCell = 30, @@ -48,7 +49,8 @@ impl ::protobuf::ProtobufEnum for GridEvent { 10 => ::std::option::Option::Some(GridEvent::GetFields), 11 => ::std::option::Option::Some(GridEvent::UpdateField), 12 => ::std::option::Option::Some(GridEvent::CreateField), - 13 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), + 13 => ::std::option::Option::Some(GridEvent::DeleteField), + 14 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), 21 => ::std::option::Option::Some(GridEvent::CreateRow), 22 => ::std::option::Option::Some(GridEvent::GetRow), 30 => ::std::option::Option::Some(GridEvent::UpdateCell), @@ -63,6 +65,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetFields, GridEvent::UpdateField, GridEvent::CreateField, + GridEvent::DeleteField, GridEvent::CreateEditFieldContext, GridEvent::CreateRow, GridEvent::GetRow, @@ -95,11 +98,12 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xa7\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xb8\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ - \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x1a\n\x16Cr\ - eateEditFieldContext\x10\r\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\ - \x10\x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\ + \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ + leteField\x10\r\x12\x1a\n\x16CreateEditFieldContext\x10\x0e\x12\r\n\tCre\ + ateRow\x10\x15\x12\n\n\x06GetRow\x10\x16\x12\x0e\n\nUpdateCell\x10\x1eb\ + \x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index f6a07a0119..36e5b81d12 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 @@ -6,7 +6,8 @@ enum GridEvent { GetFields = 10; UpdateField = 11; CreateField = 12; - CreateEditFieldContext = 13; + DeleteField = 13; + CreateEditFieldContext = 14; CreateRow = 21; GetRow = 22; UpdateCell = 30; 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 6a27fdbb72..022dc3bbfa 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -4,9 +4,8 @@ use crate::services::block_meta_editor::GridBlockMetaEditorManager; use crate::services::field::{type_option_json_str_from_bytes, FieldBuilder}; use crate::services::row::*; use bytes::Bytes; -use flowy_error::{FlowyError, FlowyResult}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; -use flowy_grid_data_model::parser::CreateFieldParams; use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use flowy_sync::client_grid::{GridChangeset, GridMetaPad}; use flowy_sync::entities::revision::Revision; @@ -87,8 +86,20 @@ impl ClientGridEditor { self.pad.read().await.contain_field(field_id) } - pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?; + pub async fn update_field(&self, mut params: FieldChangesetParams) -> FlowyResult<()> { + if let Some(type_option_data) = params.type_option_data { + match self.pad.read().await.get_field(¶ms.field_id) { + None => return Err(ErrorCode::FieldDoesNotExist.into()), + Some(field_meta) => { + // The type_option_data is serialized by protobuf. But the type_option_data should be + // serialized by utf-8 encoding. So we must transform the data here. + let type_option_json = type_option_json_str_from_bytes(type_option_data, &field_meta.field_type); + params.type_option_data = Some(type_option_json.as_bytes().to_vec()); + } + } + } + + let _ = self.modify(|grid| Ok(grid.update_field(params)?)).await?; let _ = self.notify_did_update_fields().await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 3f18e5a9c0..31ee76712e 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -64,7 +64,7 @@ async fn grid_update_field_with_empty_change() { frozen: None, visibility: None, width: None, - type_options: None, + type_option_data: None, }; let scripts = vec![ @@ -95,7 +95,7 @@ async fn grid_update_field() { frozen: Some(true), visibility: None, width: Some(1000), - type_options: Some(single_select_type_options.clone().into()), + type_option_data: Some(single_select_type_options.clone().into()), }; cloned_field.frozen = true; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index d3e5f2e909..7c813bd1e0 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -97,8 +97,11 @@ pub enum ErrorCode { RowIdIsEmpty = 430, #[display(fmt = "Field id is empty")] FieldIdIsEmpty = 440, - #[display(fmt = "Field's type option should not be empty")] - TypeOptionIsEmpty = 441, + #[display(fmt = "Field doesn't exist")] + FieldDoesNotExist = 441, + + #[display(fmt = "Field's type option data should not be empty")] + TypeOptionDataIsEmpty = 450, #[display(fmt = "Invalid data")] InvalidData = 500, diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index ffe8d5e0bc..8e6e1b9621 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -61,7 +61,8 @@ pub enum ErrorCode { BlockIdIsEmpty = 420, RowIdIsEmpty = 430, FieldIdIsEmpty = 440, - TypeOptionIsEmpty = 441, + FieldDoesNotExist = 441, + TypeOptionDataIsEmpty = 450, InvalidData = 500, } @@ -108,7 +109,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 420 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty), 430 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), 440 => ::std::option::Option::Some(ErrorCode::FieldIdIsEmpty), - 441 => ::std::option::Option::Some(ErrorCode::TypeOptionIsEmpty), + 441 => ::std::option::Option::Some(ErrorCode::FieldDoesNotExist), + 450 => ::std::option::Option::Some(ErrorCode::TypeOptionDataIsEmpty), 500 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None } @@ -152,7 +154,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::BlockIdIsEmpty, ErrorCode::RowIdIsEmpty, ErrorCode::FieldIdIsEmpty, - ErrorCode::TypeOptionIsEmpty, + ErrorCode::FieldDoesNotExist, + ErrorCode::TypeOptionDataIsEmpty, ErrorCode::InvalidData, ]; values @@ -182,7 +185,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xe4\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\x80\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\ \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\ @@ -202,8 +205,8 @@ static file_descriptor_proto_data: &'static [u8] = b"\ erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x12\n\rG\ ridIdIsEmpty\x10\x9a\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\xa4\x03\x12\x11\ \n\x0cRowIdIsEmpty\x10\xae\x03\x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\ - \x12\x16\n\x11TypeOptionIsEmpty\x10\xb9\x03\x12\x10\n\x0bInvalidData\x10\ - \xf4\x03b\x06proto3\ + \x12\x16\n\x11FieldDoesNotExist\x10\xb9\x03\x12\x1a\n\x15TypeOptionDataI\ + sEmpty\x10\xc2\x03\x12\x10\n\x0bInvalidData\x10\xf4\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index 1d3d6ed94c..e01c42aa8b 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -37,6 +37,7 @@ enum ErrorCode { BlockIdIsEmpty = 420; RowIdIsEmpty = 430; FieldIdIsEmpty = 440; - TypeOptionIsEmpty = 441; + FieldDoesNotExist = 441; + TypeOptionDataIsEmpty = 450; InvalidData = 500; } 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 a52d507c87..22d03a5993 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,5 +1,7 @@ use crate::entities::{FieldMeta, FieldType, RowMeta}; +use crate::parser::NotEmptyUuid; use flowy_derive::ProtoBuf; +use flowy_error_code::ErrorCode; use std::collections::HashMap; use std::sync::Arc; @@ -311,6 +313,24 @@ pub struct CreateRowPayload { pub start_row_id: Option, } +#[derive(Default)] +pub struct CreateRowParams { + pub grid_id: String, + pub start_row_id: Option, +} + +impl TryInto for CreateRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(CreateRowParams { + grid_id: grid_id.0, + start_row_id: self.start_row_id, + }) + } +} + #[derive(ProtoBuf, Default)] pub struct CreateFieldPayload { #[pb(index = 1)] @@ -326,6 +346,35 @@ pub struct CreateFieldPayload { pub start_field_id: Option, } +#[derive(Default, Clone)] +pub struct CreateFieldParams { + pub grid_id: String, + pub field: Field, + pub type_option_data: Vec, + pub start_field_id: Option, +} + +impl TryInto for CreateFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let _ = NotEmptyUuid::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + + let start_field_id = match self.start_field_id { + None => None, + Some(id) => Some(NotEmptyUuid::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + }; + + Ok(CreateFieldParams { + grid_id: grid_id.0, + field: self.field, + type_option_data: self.type_option_data, + start_field_id, + }) + } +} + #[derive(ProtoBuf, Default)] pub struct QueryFieldPayload { #[pb(index = 1)] @@ -335,6 +384,24 @@ pub struct QueryFieldPayload { pub field_orders: RepeatedFieldOrder, } +#[derive(Default)] +pub struct QueryFieldParams { + pub grid_id: String, + pub field_orders: RepeatedFieldOrder, +} + +impl TryInto for QueryFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryFieldParams { + grid_id: grid_id.0, + field_orders: self.field_orders, + }) + } +} + #[derive(ProtoBuf, Default)] pub struct QueryGridBlocksPayload { #[pb(index = 1)] @@ -344,6 +411,24 @@ pub struct QueryGridBlocksPayload { pub block_orders: Vec, } +#[derive(Default)] +pub struct QueryGridBlocksParams { + pub grid_id: String, + pub block_orders: Vec, +} + +impl TryInto for QueryGridBlocksPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryGridBlocksParams { + grid_id: grid_id.0, + block_orders: self.block_orders, + }) + } +} + #[derive(ProtoBuf, Default)] pub struct QueryRowPayload { #[pb(index = 1)] @@ -355,3 +440,26 @@ pub struct QueryRowPayload { #[pb(index = 3)] pub row_id: String, } + +#[derive(Default)] +pub struct QueryRowParams { + pub grid_id: String, + pub block_id: String, + pub row_id: String, +} + +impl TryInto for QueryRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let block_id = NotEmptyUuid::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(QueryRowParams { + grid_id: grid_id.0, + block_id: block_id.0, + row_id: row_id.0, + }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 24258c2d0c..90074cadff 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,4 +1,6 @@ +use crate::parser::NotEmptyUuid; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error_code::ErrorCode; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; @@ -117,7 +119,7 @@ impl FieldMeta { } #[derive(Debug, Clone, Default, ProtoBuf)] -pub struct FieldChangeset { +pub struct FieldChangesetPayload { #[pb(index = 1)] pub field_id: String, @@ -143,7 +145,47 @@ pub struct FieldChangeset { pub width: Option, #[pb(index = 9, one_of)] - pub type_options: Option, + pub type_option_data: Option>, +} + +#[derive(Debug, Clone, Default)] +pub struct FieldChangesetParams { + pub field_id: String, + pub grid_id: String, + pub name: Option, + pub desc: Option, + pub field_type: Option, + pub frozen: Option, + pub visibility: Option, + pub width: Option, + pub type_option_data: Option>, +} + +impl TryInto for FieldChangesetPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + + if let Some(type_option_data) = self.type_option_data.as_ref() { + if type_option_data.is_empty() { + return Err(ErrorCode::TypeOptionDataIsEmpty); + } + } + + Ok(FieldChangesetParams { + field_id: field_id.0, + grid_id: grid_id.0, + name: self.name, + desc: self.desc, + field_type: self.field_type, + frozen: self.frozen, + visibility: self.visibility, + width: self.width, + type_option_data: self.type_option_data, + }) + } } #[derive( diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs b/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs deleted file mode 100644 index 83f0395f53..0000000000 --- a/shared-lib/flowy-grid-data-model/src/parser/grid_params.rs +++ /dev/null @@ -1,112 +0,0 @@ -use crate::entities::{ - CreateFieldPayload, CreateRowPayload, Field, GridBlockOrder, QueryFieldPayload, QueryGridBlocksPayload, - QueryRowPayload, RepeatedFieldOrder, -}; -use crate::parser::NotEmptyUuid; -use flowy_error_code::ErrorCode; - -#[derive(Default)] -pub struct CreateRowParams { - pub grid_id: String, - pub start_row_id: Option, -} - -impl TryInto for CreateRowPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - Ok(CreateRowParams { - grid_id: grid_id.0, - start_row_id: self.start_row_id, - }) - } -} - -#[derive(Default)] -pub struct QueryFieldParams { - pub grid_id: String, - pub field_orders: RepeatedFieldOrder, -} - -impl TryInto for QueryFieldPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - Ok(QueryFieldParams { - grid_id: grid_id.0, - field_orders: self.field_orders, - }) - } -} - -#[derive(Default)] -pub struct QueryGridBlocksParams { - pub grid_id: String, - pub block_orders: Vec, -} - -impl TryInto for QueryGridBlocksPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - Ok(QueryGridBlocksParams { - grid_id: grid_id.0, - block_orders: self.block_orders, - }) - } -} - -#[derive(Default)] -pub struct QueryRowParams { - pub grid_id: String, - pub block_id: String, - pub row_id: String, -} - -impl TryInto for QueryRowPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let block_id = NotEmptyUuid::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; - let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; - - Ok(QueryRowParams { - grid_id: grid_id.0, - block_id: block_id.0, - row_id: row_id.0, - }) - } -} - -#[derive(Default, Clone)] -pub struct CreateFieldParams { - pub grid_id: String, - pub field: Field, - pub type_option_data: Vec, - pub start_field_id: Option, -} - -impl TryInto for CreateFieldPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let _ = NotEmptyUuid::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; - - let start_field_id = match self.start_field_id { - None => None, - Some(id) => Some(NotEmptyUuid::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), - }; - - Ok(CreateFieldParams { - grid_id: grid_id.0, - field: self.field, - type_option_data: self.type_option_data, - start_field_id, - }) - } -} diff --git a/shared-lib/flowy-grid-data-model/src/parser/mod.rs b/shared-lib/flowy-grid-data-model/src/parser/mod.rs index 710464f814..7cb72eb859 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/mod.rs @@ -1,5 +1,3 @@ -mod grid_params; mod id_parser; -pub use grid_params::*; pub use id_parser::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index eaea731897..f22a7c00a2 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -1139,66 +1139,66 @@ impl ::protobuf::reflect::ProtobufValue for FieldMeta { } #[derive(PartialEq,Clone,Default)] -pub struct FieldChangeset { +pub struct FieldChangesetPayload { // message fields pub field_id: ::std::string::String, pub grid_id: ::std::string::String, // message oneof groups - pub one_of_name: ::std::option::Option, - pub one_of_desc: ::std::option::Option, - pub one_of_field_type: ::std::option::Option, - pub one_of_frozen: ::std::option::Option, - pub one_of_visibility: ::std::option::Option, - pub one_of_width: ::std::option::Option, - pub one_of_type_options: ::std::option::Option, + pub one_of_name: ::std::option::Option, + pub one_of_desc: ::std::option::Option, + pub one_of_field_type: ::std::option::Option, + pub one_of_frozen: ::std::option::Option, + pub one_of_visibility: ::std::option::Option, + pub one_of_width: ::std::option::Option, + pub one_of_type_option_data: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a FieldChangeset { - fn default() -> &'a FieldChangeset { - ::default_instance() +impl<'a> ::std::default::Default for &'a FieldChangesetPayload { + fn default() -> &'a FieldChangesetPayload { + ::default_instance() } } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_name { +pub enum FieldChangesetPayload_oneof_one_of_name { name(::std::string::String), } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_desc { +pub enum FieldChangesetPayload_oneof_one_of_desc { desc(::std::string::String), } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_field_type { +pub enum FieldChangesetPayload_oneof_one_of_field_type { field_type(FieldType), } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_frozen { +pub enum FieldChangesetPayload_oneof_one_of_frozen { frozen(bool), } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_visibility { +pub enum FieldChangesetPayload_oneof_one_of_visibility { visibility(bool), } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_width { +pub enum FieldChangesetPayload_oneof_one_of_width { width(i32), } #[derive(Clone,PartialEq,Debug)] -pub enum FieldChangeset_oneof_one_of_type_options { - type_options(::std::string::String), +pub enum FieldChangesetPayload_oneof_one_of_type_option_data { + type_option_data(::std::vec::Vec), } -impl FieldChangeset { - pub fn new() -> FieldChangeset { +impl FieldChangesetPayload { + pub fn new() -> FieldChangesetPayload { ::std::default::Default::default() } @@ -1259,7 +1259,7 @@ impl FieldChangeset { pub fn get_name(&self) -> &str { match self.one_of_name { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(ref v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref v)) => v, _ => "", } } @@ -1269,24 +1269,24 @@ impl FieldChangeset { pub fn has_name(&self) -> bool { match self.one_of_name { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(..)) => true, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_name(&mut self, v: ::std::string::String) { - self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(v)) + self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) } // Mutable pointer to the field. pub fn mut_name(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(_)) = self.one_of_name { + if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(_)) = self.one_of_name { } else { - self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(::std::string::String::new())); + self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(::std::string::String::new())); } match self.one_of_name { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(ref mut v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref mut v)) => v, _ => panic!(), } } @@ -1295,7 +1295,7 @@ impl FieldChangeset { pub fn take_name(&mut self) -> ::std::string::String { if self.has_name() { match self.one_of_name.take() { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) => v, _ => panic!(), } } else { @@ -1308,7 +1308,7 @@ impl FieldChangeset { pub fn get_desc(&self) -> &str { match self.one_of_desc { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(ref v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref v)) => v, _ => "", } } @@ -1318,24 +1318,24 @@ impl FieldChangeset { pub fn has_desc(&self) -> bool { match self.one_of_desc { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(..)) => true, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_desc(&mut self, v: ::std::string::String) { - self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(v)) + self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) } // Mutable pointer to the field. pub fn mut_desc(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(_)) = self.one_of_desc { + if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(_)) = self.one_of_desc { } else { - self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(::std::string::String::new())); + self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(::std::string::String::new())); } match self.one_of_desc { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(ref mut v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref mut v)) => v, _ => panic!(), } } @@ -1344,7 +1344,7 @@ impl FieldChangeset { pub fn take_desc(&mut self) -> ::std::string::String { if self.has_desc() { match self.one_of_desc.take() { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) => v, _ => panic!(), } } else { @@ -1357,7 +1357,7 @@ impl FieldChangeset { pub fn get_field_type(&self) -> FieldType { match self.one_of_field_type { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) => v, _ => FieldType::RichText, } } @@ -1367,14 +1367,14 @@ impl FieldChangeset { pub fn has_field_type(&self) -> bool { match self.one_of_field_type { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(..)) => true, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_field_type(&mut self, v: FieldType) { - self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) + self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) } // bool frozen = 6; @@ -1382,7 +1382,7 @@ impl FieldChangeset { pub fn get_frozen(&self) -> bool { match self.one_of_frozen { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) => v, _ => false, } } @@ -1392,14 +1392,14 @@ impl FieldChangeset { pub fn has_frozen(&self) -> bool { match self.one_of_frozen { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(..)) => true, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_frozen(&mut self, v: bool) { - self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) + self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) } // bool visibility = 7; @@ -1407,7 +1407,7 @@ impl FieldChangeset { pub fn get_visibility(&self) -> bool { match self.one_of_visibility { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) => v, _ => false, } } @@ -1417,14 +1417,14 @@ impl FieldChangeset { pub fn has_visibility(&self) -> bool { match self.one_of_visibility { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(..)) => true, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_visibility(&mut self, v: bool) { - self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) + self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) } // int32 width = 8; @@ -1432,7 +1432,7 @@ impl FieldChangeset { pub fn get_width(&self) -> i32 { match self.one_of_width { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) => v, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) => v, _ => 0, } } @@ -1442,67 +1442,67 @@ impl FieldChangeset { pub fn has_width(&self) -> bool { match self.one_of_width { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(..)) => true, + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_width(&mut self, v: i32) { - self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) + self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) } - // string type_options = 9; + // bytes type_option_data = 9; - pub fn get_type_options(&self) -> &str { - match self.one_of_type_options { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v, - _ => "", + pub fn get_type_option_data(&self) -> &[u8] { + match self.one_of_type_option_data { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v)) => v, + _ => &[], } } - pub fn clear_type_options(&mut self) { - self.one_of_type_options = ::std::option::Option::None; + pub fn clear_type_option_data(&mut self) { + self.one_of_type_option_data = ::std::option::Option::None; } - pub fn has_type_options(&self) -> bool { - match self.one_of_type_options { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(..)) => true, + pub fn has_type_option_data(&self) -> bool { + match self.one_of_type_option_data { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(..)) => true, _ => false, } } // Param is passed by value, moved - pub fn set_type_options(&mut self, v: ::std::string::String) { - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) + pub fn set_type_option_data(&mut self, v: ::std::vec::Vec) { + self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) } // Mutable pointer to the field. - pub fn mut_type_options(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options { + pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec { + if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(_)) = self.one_of_type_option_data { } else { - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(::std::string::String::new())); + self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(::std::vec::Vec::new())); } - match self.one_of_type_options { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v, + match self.one_of_type_option_data { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref mut v)) => v, _ => panic!(), } } // Take field - pub fn take_type_options(&mut self) -> ::std::string::String { - if self.has_type_options() { - match self.one_of_type_options.take() { - ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v, + pub fn take_type_option_data(&mut self) -> ::std::vec::Vec { + if self.has_type_option_data() { + match self.one_of_type_option_data.take() { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) => v, _ => panic!(), } } else { - ::std::string::String::new() + ::std::vec::Vec::new() } } } -impl ::protobuf::Message for FieldChangeset { +impl ::protobuf::Message for FieldChangesetPayload { fn is_initialized(&self) -> bool { true } @@ -1521,43 +1521,43 @@ impl ::protobuf::Message for FieldChangeset { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(is.read_string()?)); + self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(is.read_string()?)); }, 4 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(is.read_string()?)); + self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(is.read_string()?)); }, 5 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(is.read_enum()?)); + self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(is.read_enum()?)); }, 6 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(is.read_bool()?)); + self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(is.read_bool()?)); }, 7 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); + self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(is.read_bool()?)); }, 8 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(is.read_int32()?)); + self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(is.read_int32()?)); }, 9 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_string()?)); + self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(is.read_bytes()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -1579,50 +1579,50 @@ impl ::protobuf::Message for FieldChangeset { } if let ::std::option::Option::Some(ref v) = self.one_of_name { match v { - &FieldChangeset_oneof_one_of_name::name(ref v) => { + &FieldChangesetPayload_oneof_one_of_name::name(ref v) => { my_size += ::protobuf::rt::string_size(3, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_desc { match v { - &FieldChangeset_oneof_one_of_desc::desc(ref v) => { + &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => { my_size += ::protobuf::rt::string_size(4, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_field_type { match v { - &FieldChangeset_oneof_one_of_field_type::field_type(v) => { + &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => { my_size += ::protobuf::rt::enum_size(5, v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_frozen { match v { - &FieldChangeset_oneof_one_of_frozen::frozen(v) => { + &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => { my_size += 2; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_visibility { match v { - &FieldChangeset_oneof_one_of_visibility::visibility(v) => { + &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => { my_size += 2; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_width { match v { - &FieldChangeset_oneof_one_of_width::width(v) => { + &FieldChangesetPayload_oneof_one_of_width::width(v) => { my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint); }, }; } - if let ::std::option::Option::Some(ref v) = self.one_of_type_options { + if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data { match v { - &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - my_size += ::protobuf::rt::string_size(9, &v); + &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => { + my_size += ::protobuf::rt::bytes_size(9, &v); }, }; } @@ -1640,50 +1640,50 @@ impl ::protobuf::Message for FieldChangeset { } if let ::std::option::Option::Some(ref v) = self.one_of_name { match v { - &FieldChangeset_oneof_one_of_name::name(ref v) => { + &FieldChangesetPayload_oneof_one_of_name::name(ref v) => { os.write_string(3, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_desc { match v { - &FieldChangeset_oneof_one_of_desc::desc(ref v) => { + &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => { os.write_string(4, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_field_type { match v { - &FieldChangeset_oneof_one_of_field_type::field_type(v) => { + &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => { os.write_enum(5, ::protobuf::ProtobufEnum::value(&v))?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_frozen { match v { - &FieldChangeset_oneof_one_of_frozen::frozen(v) => { + &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => { os.write_bool(6, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_visibility { match v { - &FieldChangeset_oneof_one_of_visibility::visibility(v) => { + &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => { os.write_bool(7, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_width { match v { - &FieldChangeset_oneof_one_of_width::width(v) => { + &FieldChangesetPayload_oneof_one_of_width::width(v) => { os.write_int32(8, v)?; }, }; } - if let ::std::option::Option::Some(ref v) = self.one_of_type_options { + if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data { match v { - &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - os.write_string(9, v)?; + &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => { + os.write_bytes(9, v)?; }, }; } @@ -1717,8 +1717,8 @@ impl ::protobuf::Message for FieldChangeset { Self::descriptor_static() } - fn new() -> FieldChangeset { - FieldChangeset::new() + fn new() -> FieldChangesetPayload { + FieldChangesetPayload::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1727,64 +1727,64 @@ impl ::protobuf::Message for FieldChangeset { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "field_id", - |m: &FieldChangeset| { &m.field_id }, - |m: &mut FieldChangeset| { &mut m.field_id }, + |m: &FieldChangesetPayload| { &m.field_id }, + |m: &mut FieldChangesetPayload| { &mut m.field_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &FieldChangeset| { &m.grid_id }, - |m: &mut FieldChangeset| { &mut m.grid_id }, + |m: &FieldChangesetPayload| { &m.grid_id }, + |m: &mut FieldChangesetPayload| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "name", - FieldChangeset::has_name, - FieldChangeset::get_name, + FieldChangesetPayload::has_name, + FieldChangesetPayload::get_name, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "desc", - FieldChangeset::has_desc, - FieldChangeset::get_desc, + FieldChangesetPayload::has_desc, + FieldChangesetPayload::get_desc, )); fields.push(::protobuf::reflect::accessor::make_singular_enum_accessor::<_, FieldType>( "field_type", - FieldChangeset::has_field_type, - FieldChangeset::get_field_type, + FieldChangesetPayload::has_field_type, + FieldChangesetPayload::get_field_type, )); fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( "frozen", - FieldChangeset::has_frozen, - FieldChangeset::get_frozen, + FieldChangesetPayload::has_frozen, + FieldChangesetPayload::get_frozen, )); fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( "visibility", - FieldChangeset::has_visibility, - FieldChangeset::get_visibility, + FieldChangesetPayload::has_visibility, + FieldChangesetPayload::get_visibility, )); fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( "width", - FieldChangeset::has_width, - FieldChangeset::get_width, + FieldChangesetPayload::has_width, + FieldChangesetPayload::get_width, )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "type_options", - FieldChangeset::has_type_options, - FieldChangeset::get_type_options, + fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor::<_>( + "type_option_data", + FieldChangesetPayload::has_type_option_data, + FieldChangesetPayload::get_type_option_data, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "FieldChangeset", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldChangesetPayload", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static FieldChangeset { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(FieldChangeset::new) + fn default_instance() -> &'static FieldChangesetPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldChangesetPayload::new) } } -impl ::protobuf::Clear for FieldChangeset { +impl ::protobuf::Clear for FieldChangesetPayload { fn clear(&mut self) { self.field_id.clear(); self.grid_id.clear(); @@ -1794,18 +1794,18 @@ impl ::protobuf::Clear for FieldChangeset { self.one_of_frozen = ::std::option::Option::None; self.one_of_visibility = ::std::option::Option::None; self.one_of_width = ::std::option::Option::None; - self.one_of_type_options = ::std::option::Option::None; + self.one_of_type_option_data = ::std::option::Option::None; self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for FieldChangeset { +impl ::std::fmt::Debug for FieldChangesetPayload { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for FieldChangeset { +impl ::protobuf::reflect::ProtobufValue for FieldChangesetPayload { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3514,43 +3514,44 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ idth\x12(\n\x10type_option_json\x18\x08\x20\x01(\tR\x0etypeOptionJson\"\ - \x96\x03\n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\ - \x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\ - \x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\ - \x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTy\ - peH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06fr\ - ozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\ - \x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12#\n\x0ctype_optio\ - ns\x18\t\x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone\ - _of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one\ - _of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"8\n\ - \x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\ - \x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\ - \n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01\ - (\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.Row\ - Meta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\ - \x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibi\ - lity\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ - \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ - \x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\ - \x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06he\ - ight\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\ - \x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByField\ - IdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ + \xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ + \x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ + \x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n\ + .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\ + \x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibi\ + lity\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10ty\ + pe_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of\ + _nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_fro\ + zenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_\ + type_option_data\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\t\ + R\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\ + \n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08blo\ + ck_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\ + \x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\ + \x06height\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\ + \x20\x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ \x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.C\ - ellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visib\ - ility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fiel\ - dId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMet\ - aChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\ - \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\ - \x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04data\ - B\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bfield_met\ - as\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bblock_metas\ - \x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fblock_me\ - ta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaData*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\ + ellMetaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\ + \x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\ + \x01(\x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\ + \nvisibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaCh\ + angeset.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\ + \x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\ + \x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\ + \n\x11one_of_visibility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\ + \x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\ + \x83\x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\ + \x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\ + \x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridCont\ + ext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\ + \x12/\n\x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMe\ + tas\x12;\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSer\ + deR\rblockMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\ + \x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSele\ + ct\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\ + \x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 44ed367956..2c5bd41f86 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -24,7 +24,7 @@ message FieldMeta { int32 width = 7; string type_option_json = 8; } -message FieldChangeset { +message FieldChangesetPayload { string field_id = 1; string grid_id = 2; oneof one_of_name { string name = 3; }; @@ -33,7 +33,7 @@ message FieldChangeset { oneof one_of_frozen { bool frozen = 6; }; oneof one_of_visibility { bool visibility = 7; }; oneof one_of_width { int32 width = 8; }; - oneof one_of_type_options { string type_options = 9; }; + oneof one_of_type_option_data { bytes type_option_data = 9; }; } message AnyData { string type_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 9375f80ed0..e1712d2584 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -3,12 +3,13 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ - FieldChangeset, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, + FieldChangesetParams, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; +use std::string::FromUtf8Error; use std::sync::Arc; pub type GridMetaDelta = PlainTextDelta; @@ -109,7 +110,7 @@ impl GridMetaPad { } } - pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { + pub fn update_field(&mut self, changeset: FieldChangesetParams) -> CollaborateResult> { let field_id = changeset.field_id.clone(); self.modify_field(&field_id, |field| { let mut is_changed = None; @@ -143,9 +144,16 @@ impl GridMetaPad { is_changed = Some(()) } - if let Some(type_options) = changeset.type_options { - field.type_option_json = type_options; - is_changed = Some(()) + if let Some(type_option_data) = changeset.type_option_data { + match String::from_utf8(type_option_data) { + Ok(type_option_json) => { + field.type_option_json = type_option_json; + is_changed = Some(()) + } + Err(err) => { + tracing::error!("Deserialize data to type option json failed: {}", err); + } + } } Ok(is_changed) From 8b7eee46bb32dca090548f5f36baa7d4db0bcf4c Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 27 Mar 2022 11:14:21 +0800 Subject: [PATCH 065/179] chore: duplicate and hide field --- .../grid/field/create_field_bloc.dart | 1 + .../grid/field/edit_field_bloc.dart | 31 +- .../application/grid/field/field_service.dart | 26 +- .../plugins/grid/src/grid_page.dart | 2 +- .../src/widgets/header/edit_field_pannel.dart | 26 +- .../widgets/header/field_operation_list.dart | 31 +- .../grid/src/widgets/header/header.dart | 123 ----- .../grid/src/widgets/header/header_cell.dart | 36 -- .../lib/style_widget/button.dart | 3 +- .../dart_event/flowy-grid/dart_event.dart | 21 +- .../flowy-grid-data-model/grid.pb.dart | 122 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 22 + .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 5 +- .../rust-lib/flowy-grid/src/event_handler.rs | 17 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 12 +- .../src/protobuf/model/event_map.rs | 15 +- .../src/protobuf/proto/event_map.proto | 3 +- .../flowy-grid/src/services/grid_editor.rs | 11 +- .../src/entities/grid.rs | 31 ++ .../src/protobuf/model/grid.rs | 489 ++++++++++++++++-- .../src/protobuf/proto/grid.proto | 8 + .../src/client_grid/grid_meta_pad.rs | 83 +-- 23 files changed, 835 insertions(+), 287 deletions(-) delete mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart delete mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart index 29f7187c2f..6a5a276214 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart @@ -62,6 +62,7 @@ class CreateFieldBloc extends Bloc { emit(state.copyWith( field: Some(editContext.gridField), typeOptionData: editContext.typeOptionData, + fieldName: editContext.gridField.name, )); }, (err) => Log.error(err), diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart index 11dbe765fc..6b92b0d0d5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -18,9 +19,27 @@ class EditFieldBloc extends Bloc { updateFieldName: (_UpdateFieldName value) { // }, - hideField: (_HideField value) {}, - deleteField: (_DeleteField value) {}, - duplicateField: (_DuplicateField value) {}, + hideField: (_HideField value) async { + final result = await service.updateField(fieldId: value.fieldId, visibility: false); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + deleteField: (_DeleteField value) async { + final result = await service.deleteField(fieldId: value.fieldId); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + duplicateField: (_DuplicateField value) async { + final result = await service.duplicateField(fieldId: value.fieldId); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, saveField: (_SaveField value) {}, ); }, @@ -37,9 +56,9 @@ class EditFieldBloc extends Bloc { class EditFieldEvent with _$EditFieldEvent { const factory EditFieldEvent.initial() = _InitialField; const factory EditFieldEvent.updateFieldName(String name) = _UpdateFieldName; - const factory EditFieldEvent.hideField() = _HideField; - const factory EditFieldEvent.duplicateField() = _DuplicateField; - const factory EditFieldEvent.deleteField() = _DeleteField; + const factory EditFieldEvent.hideField(String fieldId) = _HideField; + const factory EditFieldEvent.duplicateField(String fieldId) = _DuplicateField; + const factory EditFieldEvent.deleteField(String fieldId) = _DeleteField; const factory EditFieldEvent.saveField() = _SaveField; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 84566da604..6824ce0b1b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -21,7 +21,7 @@ class FieldService { } Future> updateField({ - required Field field, + required String fieldId, String? name, FieldType? fieldType, bool? frozen, @@ -29,7 +29,9 @@ class FieldService { double? width, List? typeOptionData, }) { - var payload = FieldChangesetPayload.create()..gridId = gridId; + var payload = FieldChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId; if (name != null) { payload.name = name; @@ -74,6 +76,26 @@ class FieldService { return GridEventCreateField(payload).send(); } + + Future> deleteField({ + required String fieldId, + }) { + final payload = FieldIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId; + + return GridEventDeleteField(payload).send(); + } + + Future> duplicateField({ + required String fieldId, + }) { + final payload = FieldIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId; + + return GridEventDuplicateField(payload).send(); + } } class GridFieldData extends Equatable { 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 5cd23accc6..e1c44c253b 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 @@ -13,7 +13,7 @@ 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'; +import 'widgets/header/grid_header.dart'; class GridPage extends StatefulWidget { final View view; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart index 47affb67e8..ce542b6760 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart @@ -2,7 +2,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -38,9 +37,7 @@ class EditFieldPannel extends StatelessWidget { const VSpace(6), const _FieldTypeSwitcher(), const VSpace(6), - FieldOperationList( - onDismiss: () => FlowyOverlay.of(context).remove(identifier()), - ), + _FieldOperationList(fieldData, () => FlowyOverlay.of(context).remove(identifier())), ], ), ), @@ -52,6 +49,27 @@ class EditFieldPannel extends StatelessWidget { } } +class _FieldOperationList extends StatelessWidget { + final GridFieldData fieldData; + final VoidCallback onDismissed; + const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final actions = FieldAction.values + .map( + (action) => FieldActionItem( + fieldId: fieldData.field.id, + action: action, + onTap: onDismissed, + ), + ) + .toList(); + + return FieldOperationList(actions: actions); + } +} + class _FieldTypeSwitcher extends StatelessWidget { const _FieldTypeSwitcher({Key? key}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart index fb639e5f5b..ddf5eb7660 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart @@ -9,17 +9,11 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class FieldOperationList extends StatelessWidget { - final VoidCallback onDismiss; - const FieldOperationList({required this.onDismiss, Key? key}) : super(key: key); + final List actions; + const FieldOperationList({required this.actions, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final children = FieldAction.values - .map((action) => FieldActionItem( - action: action, - onTap: onDismiss, - )) - .toList(); return GridView( // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html shrinkWrap: true, @@ -28,15 +22,22 @@ class FieldOperationList extends StatelessWidget { childAspectRatio: 4.0, mainAxisSpacing: 8, ), - children: children, + children: actions, ); } } class FieldActionItem extends StatelessWidget { + final String fieldId; final VoidCallback onTap; final FieldAction action; - const FieldActionItem({required this.action, required this.onTap, Key? key}) : super(key: key); + + const FieldActionItem({ + required this.fieldId, + required this.action, + required this.onTap, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -45,7 +46,7 @@ class FieldActionItem extends StatelessWidget { text: FlowyText.medium(action.title(), fontSize: 12), hoverColor: theme.hover, onTap: () { - action.run(context); + action.run(context, fieldId); onTap(); }, leftIcon: svg(action.iconName(), color: theme.iconColor), @@ -82,16 +83,16 @@ extension _FieldActionExtension on FieldAction { } } - void run(BuildContext context) { + void run(BuildContext context, String fieldId) { switch (this) { case FieldAction.hide: - context.read().add(const EditFieldEvent.hideField()); + context.read().add(EditFieldEvent.hideField(fieldId)); break; case FieldAction.duplicate: - context.read().add(const EditFieldEvent.duplicateField()); + context.read().add(EditFieldEvent.duplicateField(fieldId)); break; case FieldAction.delete: - context.read().add(const EditFieldEvent.deleteField()); + context.read().add(EditFieldEvent.deleteField(fieldId)); break; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart deleted file mode 100644 index dbebb311b9..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import 'create_field_pannel.dart'; -import 'header_cell.dart'; - -class GridHeaderDelegate extends SliverPersistentHeaderDelegate { - final String gridId; - final List fields; - - GridHeaderDelegate({required this.gridId, required this.fields}); - - @override - Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return GridHeader(gridId: gridId, fields: fields, key: ObjectKey(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; - final String gridId; - const GridHeader({required this.gridId, required this.fields, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return BlocProvider( - create: (context) { - final bloc = getIt(param1: gridId, param2: fields); - bloc.add(const GridHeaderEvent.initial()); - return bloc; - }, - child: BlocBuilder( - builder: (context, state) { - final cells = state.fields.map( - (field) => HeaderCell( - GridFieldData(gridId: gridId, field: field), - ), - ); - - final row = Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _HeaderLeading(), - ...cells, - _HeaderTrailing(gridId: gridId), - ], - ); - - return Container(color: theme.surface, child: row); - }, - ), - ); - } -} - -class _HeaderLeading extends StatelessWidget { - const _HeaderLeading({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - width: GridSize.leadingHeaderPadding, - ); - } -} - -class _HeaderTrailing extends StatelessWidget { - final String gridId; - const _HeaderTrailing({required this.gridId, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - return Container( - width: GridSize.trailHeaderPadding, - decoration: BoxDecoration( - border: Border(top: borderSide, bottom: borderSide), - ), - padding: GridSize.headerContentInsets, - child: CreateFieldButton(gridId: gridId), - ); - } -} - -class CreateFieldButton extends StatelessWidget { - final String gridId; - const CreateFieldButton({required this.gridId, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return FlowyButton( - text: const FlowyText.medium('New column', fontSize: 12), - hoverColor: theme.hover, - onTap: () => CreateFieldPannel(gridId: gridId).show(context, gridId), - leftIcon: svg("home/add"), - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart deleted file mode 100755 index 52e7e38d75..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import 'edit_field_pannel.dart'; - -class HeaderCell extends StatelessWidget { - final GridFieldData fieldData; - const HeaderCell(this.fieldData, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - final button = FlowyButton( - hoverColor: theme.hover, - onTap: () => EditFieldPannel.show(context, fieldData), - rightIcon: svg("editor/details", color: theme.iconColor), - text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), - ); - - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); - - return Container( - width: fieldData.field.width.toDouble(), - decoration: decoration, - padding: GridSize.headerContentInsets, - child: button, - ); - } -} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 78d65a9941..0bcd05f56e 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -40,10 +40,9 @@ class FlowyButton extends StatelessWidget { children.add(const HSpace(6)); } - children.add(text); + children.add(Expanded(child: text)); if (rightIcon != null) { - children.add(const Spacer()); children.add(SizedBox.fromSize(size: const Size.square(16), child: rightIcon!)); children.add(const HSpace(6)); } 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 0c3d242c37..7f25329284 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -53,7 +53,7 @@ class GridEventGetFields { } class GridEventUpdateField { - FieldChangeset request; + FieldChangesetPayload request; GridEventUpdateField(this.request); Future> send() { @@ -87,7 +87,7 @@ class GridEventCreateField { } class GridEventDeleteField { - FieldOrder request; + FieldIdentifierPayload request; GridEventDeleteField(this.request); Future> send() { @@ -103,6 +103,23 @@ class GridEventDeleteField { } } +class GridEventDuplicateField { + FieldIdentifierPayload request; + GridEventDuplicateField(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.DuplicateField.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateEditFieldContext { CreateEditFieldContextParams request; GridEventCreateEditFieldContext(this.request); 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 4ea447d729..bd9afe2243 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 @@ -205,6 +205,128 @@ class Field extends $pb.GeneratedMessage { void clearWidth() => clearField(7); } +class FieldIdentifierPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldIdentifierPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..hasRequiredFields = false + ; + + FieldIdentifierPayload._() : super(); + factory FieldIdentifierPayload({ + $core.String? fieldId, + $core.String? gridId, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (gridId != null) { + _result.gridId = gridId; + } + return _result; + } + factory FieldIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldIdentifierPayload.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') + FieldIdentifierPayload clone() => FieldIdentifierPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldIdentifierPayload copyWith(void Function(FieldIdentifierPayload) updates) => super.copyWith((message) => updates(message as FieldIdentifierPayload)) as FieldIdentifierPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldIdentifierPayload create() => FieldIdentifierPayload._(); + FieldIdentifierPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldIdentifierPayload? _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.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); +} + +class FieldIdentifierParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldIdentifierParams', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..hasRequiredFields = false + ; + + FieldIdentifierParams._() : super(); + factory FieldIdentifierParams({ + $core.String? fieldId, + $core.String? gridId, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (gridId != null) { + _result.gridId = gridId; + } + return _result; + } + factory FieldIdentifierParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldIdentifierParams.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') + FieldIdentifierParams clone() => FieldIdentifierParams()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldIdentifierParams copyWith(void Function(FieldIdentifierParams) updates) => super.copyWith((message) => updates(message as FieldIdentifierParams)) as FieldIdentifierParams; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldIdentifierParams create() => FieldIdentifierParams._(); + FieldIdentifierParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldIdentifierParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldIdentifierParams? _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.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); +} + 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') 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 a7dc3255c8..0b900d46f9 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 @@ -36,6 +36,28 @@ const Field$json = const { /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aA=='); +@$core.Deprecated('Use fieldIdentifierPayloadDescriptor instead') +const FieldIdentifierPayload$json = const { + '1': 'FieldIdentifierPayload', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + ], +}; + +/// Descriptor for `FieldIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldIdentifierPayloadDescriptor = $convert.base64Decode('ChZGaWVsZElkZW50aWZpZXJQYXlsb2FkEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZA=='); +@$core.Deprecated('Use fieldIdentifierParamsDescriptor instead') +const FieldIdentifierParams$json = const { + '1': 'FieldIdentifierParams', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + ], +}; + +/// Descriptor for `FieldIdentifierParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldIdentifierParamsDescriptor = $convert.base64Decode('ChVGaWVsZElkZW50aWZpZXJQYXJhbXMSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElk'); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', 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 755b1c1ed1..46291923e0 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 @@ -16,7 +16,8 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField'); - static const GridEvent CreateEditFieldContext = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); + static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); + static const GridEvent CreateEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); @@ -28,6 +29,7 @@ class GridEvent extends $pb.ProtobufEnum { UpdateField, CreateField, DeleteField, + DuplicateField, CreateEditFieldContext, CreateRow, GetRow, 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 9441a03bea..278e0b14c3 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 @@ -18,7 +18,8 @@ const GridEvent$json = const { const {'1': 'UpdateField', '2': 11}, const {'1': 'CreateField', '2': 12}, const {'1': 'DeleteField', '2': 13}, - const {'1': 'CreateEditFieldContext', '2': 14}, + const {'1': 'DuplicateField', '2': 15}, + const {'1': 'CreateEditFieldContext', '2': 16}, const {'1': 'CreateRow', '2': 21}, const {'1': 'GetRow', '2': 22}, const {'1': 'UpdateCell', '2': 30}, @@ -26,4 +27,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SGgoWQ3JlYXRlRWRpdEZpZWxkQ29udGV4dBAOEg0KCUNyZWF0ZVJvdxAVEgoKBkdldFJvdxAWEg4KClVwZGF0ZUNlbGwQHg=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIaChZDcmVhdGVFZGl0RmllbGRDb250ZXh0EBASDQoJQ3JlYXRlUm93EBUSCgoGR2V0Um93EBYSDgoKVXBkYXRlQ2VsbBAe'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e16c761cb2..97b91e5557 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -68,12 +68,23 @@ pub(crate) async fn create_field_handler( #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn delete_field_handler( - data: Data, + data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let field_order: FieldOrder = data.into_inner(); + let params: FieldIdentifierParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let _ = editor.delete_field(&field_order.field_id).await?; + let _ = editor.delete_field(¶ms.field_id).await?; + Ok(()) +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn duplicate_field_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let params: FieldIdentifierParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.duplicate_field(¶ms.field_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 9819f2142e..efe5ddc094 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -13,7 +13,8 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) - .event(GridEvent::DeleteField, create_field_handler) + .event(GridEvent::DeleteField, delete_field_handler) + .event(GridEvent::DuplicateField, duplicate_field_handler) .event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) @@ -34,17 +35,20 @@ pub enum GridEvent { #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 10, - #[event(input = "FieldChangeset")] + #[event(input = "FieldChangesetPayload")] UpdateField = 11, #[event(input = "CreateFieldPayload")] CreateField = 12, - #[event(input = "FieldOrder")] + #[event(input = "FieldIdentifierPayload")] DeleteField = 13, + #[event(input = "FieldIdentifierPayload")] + DuplicateField = 15, + #[event(input = "CreateEditFieldContextParams", output = "EditFieldContext")] - CreateEditFieldContext = 14, + CreateEditFieldContext = 16, #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 21, 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 dfa0f30b74..13ee0705cc 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 @@ -31,7 +31,8 @@ pub enum GridEvent { UpdateField = 11, CreateField = 12, DeleteField = 13, - CreateEditFieldContext = 14, + DuplicateField = 15, + CreateEditFieldContext = 16, CreateRow = 21, GetRow = 22, UpdateCell = 30, @@ -50,7 +51,8 @@ impl ::protobuf::ProtobufEnum for GridEvent { 11 => ::std::option::Option::Some(GridEvent::UpdateField), 12 => ::std::option::Option::Some(GridEvent::CreateField), 13 => ::std::option::Option::Some(GridEvent::DeleteField), - 14 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), + 15 => ::std::option::Option::Some(GridEvent::DuplicateField), + 16 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), 21 => ::std::option::Option::Some(GridEvent::CreateRow), 22 => ::std::option::Option::Some(GridEvent::GetRow), 30 => ::std::option::Option::Some(GridEvent::UpdateCell), @@ -66,6 +68,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::UpdateField, GridEvent::CreateField, GridEvent::DeleteField, + GridEvent::DuplicateField, GridEvent::CreateEditFieldContext, GridEvent::CreateRow, GridEvent::GetRow, @@ -98,12 +101,12 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xb8\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xcc\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ - leteField\x10\r\x12\x1a\n\x16CreateEditFieldContext\x10\x0e\x12\r\n\tCre\ - ateRow\x10\x15\x12\n\n\x06GetRow\x10\x16\x12\x0e\n\nUpdateCell\x10\x1eb\ - \x06proto3\ + leteField\x10\r\x12\x12\n\x0eDuplicateField\x10\x0f\x12\x1a\n\x16CreateE\ + ditFieldContext\x10\x10\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\x10\ + \x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index 36e5b81d12..327a1e3aee 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 @@ -7,7 +7,8 @@ enum GridEvent { UpdateField = 11; CreateField = 12; DeleteField = 13; - CreateEditFieldContext = 14; + DuplicateField = 15; + CreateEditFieldContext = 16; CreateRow = 21; GetRow = 22; UpdateCell = 30; 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 022dc3bbfa..7ff089ff9b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -110,6 +110,12 @@ impl ClientGridEditor { Ok(()) } + pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.duplicate_field(field_id)?)).await?; + let _ = self.notify_did_update_fields().await?; + Ok(()) + } + pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; Ok(()) @@ -254,8 +260,9 @@ impl ClientGridEditor { } pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { - let field_meta = self.pad.read().await.get_field_metas(field_orders)?; - Ok(field_meta) + let mut field_metas = self.pad.read().await.get_field_metas(field_orders)?; + field_metas.retain(|field_meta| field_meta.visibility); + Ok(field_metas) } pub async fn get_block_meta_data_vec( 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 22d03a5993..dfd5dc397f 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -55,6 +55,37 @@ impl std::convert::From for Field { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldIdentifierPayload { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] + pub grid_id: String, +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldIdentifierParams { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] + pub grid_id: String, +} + +impl TryInto for FieldIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + Ok(FieldIdentifierParams { + grid_id: grid_id.0, + field_id: field_id.0, + }) + } +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[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 a6afa46d9a..c18043184f 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 @@ -659,6 +659,408 @@ impl ::protobuf::reflect::ProtobufValue for Field { } } +#[derive(PartialEq,Clone,Default)] +pub struct FieldIdentifierPayload { + // message fields + pub field_id: ::std::string::String, + pub grid_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a FieldIdentifierPayload { + fn default() -> &'a FieldIdentifierPayload { + ::default_instance() + } +} + +impl FieldIdentifierPayload { + pub fn new() -> FieldIdentifierPayload { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string 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()) + } +} + +impl ::protobuf::Message for FieldIdentifierPayload { + 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 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_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.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_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() -> FieldIdentifierPayload { + FieldIdentifierPayload::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: &FieldIdentifierPayload| { &m.field_id }, + |m: &mut FieldIdentifierPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &FieldIdentifierPayload| { &m.grid_id }, + |m: &mut FieldIdentifierPayload| { &mut m.grid_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldIdentifierPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldIdentifierPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldIdentifierPayload::new) + } +} + +impl ::protobuf::Clear for FieldIdentifierPayload { + fn clear(&mut self) { + self.field_id.clear(); + self.grid_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldIdentifierPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldIdentifierPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct FieldIdentifierParams { + // message fields + pub field_id: ::std::string::String, + pub grid_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a FieldIdentifierParams { + fn default() -> &'a FieldIdentifierParams { + ::default_instance() + } +} + +impl FieldIdentifierParams { + pub fn new() -> FieldIdentifierParams { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string 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()) + } +} + +impl ::protobuf::Message for FieldIdentifierParams { + 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 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_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.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_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() -> FieldIdentifierParams { + FieldIdentifierParams::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: &FieldIdentifierParams| { &m.field_id }, + |m: &mut FieldIdentifierParams| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &FieldIdentifierParams| { &m.grid_id }, + |m: &mut FieldIdentifierParams| { &mut m.grid_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldIdentifierParams", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldIdentifierParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldIdentifierParams::new) + } +} + +impl ::protobuf::Clear for FieldIdentifierParams { + fn clear(&mut self) { + self.field_id.clear(); + self.grid_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldIdentifierParams { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldIdentifierParams { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -4865,48 +5267,51 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\ \x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\ \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ - \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"b\n\x1cCreateEditFiel\ - dContextParams\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12)\n\ - \nfield_type\x18\x02\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditF\ - ieldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ng\ - rid_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_opt\ - ion_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ - \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ - edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ - ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ - t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ - \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ - \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ - \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ - .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ - \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ - items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\ - \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ - \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ - \x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b\ - 2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\ - \x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\ - \x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01\ - (\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstart\ - RowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\ - \x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ - \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ - \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ - \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ - \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ - \x0f.GridBlockOrderR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ - \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ - b\x06proto3\ + \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"L\n\x16FieldIdentifi\ + erPayload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\ + \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"K\n\x15FieldIdentifierParams\ + \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ + id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08field_id\ + \x18\x01\x20\x01(\tR\x07fieldId\"b\n\x1cCreateEditFieldContextParams\x12\ + \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12)\n\nfield_type\x18\ + \x02\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\ + \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\ + \x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\ + \x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05it\ + ems\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ + RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ + lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ + yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ + \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ + (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ + \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ + \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ + \x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\ + \x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ + 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ + \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ + \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ + R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ + lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ + \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ + idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ + \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ + rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ + \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ + \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ + \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ + ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ + ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ + \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ + ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ + \x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ + \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ + kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index ec109f580f..3a74e23026 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 @@ -15,6 +15,14 @@ message Field { bool visibility = 6; int32 width = 7; } +message FieldIdentifierPayload { + string field_id = 1; + string grid_id = 2; +} +message FieldIdentifierParams { + string field_id = 1; + string grid_id = 2; +} message FieldOrder { string field_id = 1; } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index e1712d2584..78c0091b57 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -72,42 +72,17 @@ impl GridMetaPad { }) } - pub fn contain_field(&self, field_id: &str) -> bool { - self.grid_meta.fields.iter().any(|field| field.id == field_id) - } - - pub fn get_field(&self, field_id: &str) -> Option<&FieldMeta> { - self.grid_meta.fields.iter().find(|field| field.id == field_id) - } - - pub fn get_field_orders(&self) -> Vec { - self.grid_meta.fields.iter().map(FieldOrder::from).collect() - } - - pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { - match field_orders { - None => Ok(self.grid_meta.fields.clone()), - Some(field_orders) => { - let field_by_field_id = self - .grid_meta - .fields - .iter() - .map(|field| (&field.id, field)) - .collect::>(); - - let fields = field_orders - .iter() - .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { - None => { - tracing::error!("Can't find the field with id: {}", field_order.field_id); - None - } - Some(field) => Some((*field).clone()), - }) - .collect::>(); - Ok(fields) + pub fn duplicate_field(&mut self, field_id: &str) -> CollaborateResult> { + self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + let mut duplicate_field_meta = grid.fields[index].clone(); + duplicate_field_meta.id = uuid(); + duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); + grid.fields.insert(index + 1, duplicate_field_meta); + Ok(Some(())) } - } + }) } pub fn update_field(&mut self, changeset: FieldChangesetParams) -> CollaborateResult> { @@ -160,6 +135,44 @@ impl GridMetaPad { }) } + pub fn get_field(&self, field_id: &str) -> Option<&FieldMeta> { + self.grid_meta.fields.iter().find(|field| field.id == field_id) + } + + pub fn contain_field(&self, field_id: &str) -> bool { + self.grid_meta.fields.iter().any(|field| field.id == field_id) + } + + pub fn get_field_orders(&self) -> Vec { + self.grid_meta.fields.iter().map(FieldOrder::from).collect() + } + + pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { + match field_orders { + None => Ok(self.grid_meta.fields.clone()), + Some(field_orders) => { + let field_by_field_id = self + .grid_meta + .fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let fields = field_orders + .iter() + .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { + None => { + tracing::error!("Can't find the field with id: {}", field_order.field_id); + None + } + Some(field) => Some((*field).clone()), + }) + .collect::>(); + Ok(fields) + } + } + } + pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid| { if grid.block_metas.iter().any(|b| b.block_id == block.block_id) { From 35e27b579f3cbd07fc1a1e780d9675810acfa64e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 27 Mar 2022 22:38:50 +0800 Subject: [PATCH 066/179] chore: number field --- .../assets/images/grid/field/euro.svg | 3 + .../assets/images/grid/field/numbers.svg | 3 + .../assets/images/grid/field/us_dollar.svg | 3 + .../assets/images/grid/field/yen.svg | 3 + .../app_flowy/assets/translations/en.json | 5 +- .../app_flowy/lib/startup/deps_resolver.dart | 5 +- .../grid/field/edit_field_bloc.dart | 22 ++- .../grid/field/grid_header_bloc.dart | 26 ++- .../grid/field/grid_header_listener.dart | 0 .../grid/{ => field}/grid_listenr.dart | 14 +- .../grid/field/switch_field_type_bloc.dart | 4 + .../grid/field/type_option/number_bloc.dart | 23 ++- .../workspace/application/grid/grid_bloc.dart | 24 +-- .../application/grid/row/row_bloc.dart | 11 +- .../application/grid/row/row_listener.dart | 41 +---- .../plugins/grid/src/grid_page.dart | 2 - .../grid/src/widgets/content/grid_row.dart | 59 ++++--- .../widgets/header/create_field_pannel.dart | 2 +- .../src/widgets/header/edit_field_pannel.dart | 4 +- .../widgets/header/field_operation_list.dart | 10 +- .../widgets/header/field_tyep_switcher.dart | 71 +++----- .../grid/src/widgets/header/grid_header.dart | 123 +++++++++++++ .../src/widgets/header/grid_header_cell.dart | 36 ++++ .../widgets/header/type_option/number.dart | 165 ++++++++++++++++++ 24 files changed, 492 insertions(+), 167 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/field/euro.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/numbers.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/us_dollar.svg create mode 100644 frontend/app_flowy/assets/images/grid/field/yen.svg create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/grid_header_listener.dart rename frontend/app_flowy/lib/workspace/application/grid/{ => field}/grid_listenr.dart (75%) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart diff --git a/frontend/app_flowy/assets/images/grid/field/euro.svg b/frontend/app_flowy/assets/images/grid/field/euro.svg new file mode 100644 index 0000000000..95f511f687 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/euro.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/assets/images/grid/field/numbers.svg b/frontend/app_flowy/assets/images/grid/field/numbers.svg new file mode 100644 index 0000000000..9d8b98d10d --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/numbers.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/assets/images/grid/field/us_dollar.svg b/frontend/app_flowy/assets/images/grid/field/us_dollar.svg new file mode 100644 index 0000000000..a8485cd6a1 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/us_dollar.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/assets/images/grid/field/yen.svg b/frontend/app_flowy/assets/images/grid/field/yen.svg new file mode 100644 index 0000000000..8e9bf47c99 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/field/yen.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 5e5fc661ec..1031265da1 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -152,9 +152,10 @@ "textFieldName": "Text", "checkboxFieldName": "Checkbox", "dateFieldName": "Date", - "numberFieldName": "Number", + "numberFieldName": "Numbers", "singleSelectFieldName": "Select", - "multiSelectFieldName": "Multiselect" + "multiSelectFieldName": "Multiselect", + "numberFormat": " Number format" } } } diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 8293efd652..e277bc6a20 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -18,6 +18,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -221,7 +222,7 @@ void _resolveGridDeps(GetIt getIt) { () => DateTypeOptionBloc(), ); - getIt.registerFactory( - () => NumberTypeOptionBloc(), + getIt.registerFactoryParam( + (typeOption, _) => NumberTypeOptionBloc(typeOption: typeOption), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart index 6b92b0d0d5..525d5232d7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart @@ -16,25 +16,29 @@ class EditFieldBloc extends Bloc { (event, emit) async { await event.map( initial: (_InitialField value) {}, - updateFieldName: (_UpdateFieldName value) { - // + updateFieldName: (_UpdateFieldName value) async { + final result = await service.updateField(fieldId: field.id, name: value.name); + result.fold( + (l) => null, + (err) => Log.error(err), + ); }, hideField: (_HideField value) async { - final result = await service.updateField(fieldId: value.fieldId, visibility: false); + final result = await service.updateField(fieldId: field.id, visibility: false); result.fold( (l) => null, (err) => Log.error(err), ); }, deleteField: (_DeleteField value) async { - final result = await service.deleteField(fieldId: value.fieldId); + final result = await service.deleteField(fieldId: field.id); result.fold( (l) => null, (err) => Log.error(err), ); }, duplicateField: (_DuplicateField value) async { - final result = await service.duplicateField(fieldId: value.fieldId); + final result = await service.duplicateField(fieldId: field.id); result.fold( (l) => null, (err) => Log.error(err), @@ -56,9 +60,9 @@ class EditFieldBloc extends Bloc { class EditFieldEvent with _$EditFieldEvent { const factory EditFieldEvent.initial() = _InitialField; const factory EditFieldEvent.updateFieldName(String name) = _UpdateFieldName; - const factory EditFieldEvent.hideField(String fieldId) = _HideField; - const factory EditFieldEvent.duplicateField(String fieldId) = _DuplicateField; - const factory EditFieldEvent.deleteField(String fieldId) = _DeleteField; + const factory EditFieldEvent.hideField() = _HideField; + const factory EditFieldEvent.duplicateField() = _DuplicateField; + const factory EditFieldEvent.deleteField() = _DeleteField; const factory EditFieldEvent.saveField() = _SaveField; } @@ -67,10 +71,12 @@ class EditFieldState with _$EditFieldState { const factory EditFieldState({ required EditFieldContext editContext, required String errorText, + required String fieldName, }) = _EditFieldState; factory EditFieldState.initial(EditFieldContext editContext) => EditFieldState( editContext: editContext, errorText: '', + fieldName: editContext.gridField.name, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart index a5f3a8414a..d249e9b4c1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -1,4 +1,6 @@ import 'package:app_flowy/workspace/application/grid/data.dart'; +import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -9,24 +11,43 @@ part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc { final FieldService service; + final GridFieldsListener fieldListener; GridHeaderBloc({ required GridHeaderData data, required this.service, - }) : super(GridHeaderState.initial(data.fields)) { + }) : fieldListener = GridFieldsListener(gridId: data.gridId), + super(GridHeaderState.initial(data.fields)) { on( (event, emit) async { await event.map( - initial: (_InitialHeader value) async {}, + initial: (_InitialHeader value) async { + _startListening(); + }, createField: (_CreateField value) {}, insertField: (_InsertField value) {}, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + emit(state.copyWith(fields: value.fields)); + }, ); }, ); } + Future _startListening() async { + fieldListener.updateFieldsNotifier.addPublishListener((result) { + result.fold( + (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), + (err) => Log.error(err), + ); + }); + + fieldListener.start(); + } + @override Future close() async { + await fieldListener.stop(); return super.close(); } } @@ -36,6 +57,7 @@ class GridHeaderEvent with _$GridHeaderEvent { const factory GridHeaderEvent.initial() = _InitialHeader; const factory GridHeaderEvent.createField() = _CreateField; const factory GridHeaderEvent.insertField({required bool onLeft}) = _InsertField; + const factory GridHeaderEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_listener.dart new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart similarity index 75% rename from frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index 4afaa54601..60ff7dd415 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -9,14 +9,14 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -// typedef RowsUpdateNotifierValue = Either, FlowyError>; +typedef UpdateFieldNotifiedValue = Either, FlowyError>; -class GridListener { +class GridFieldsListener { final String gridId; - PublishNotifier, FlowyError>> fieldsUpdateNotifier = PublishNotifier(); + PublishNotifier updateFieldsNotifier = PublishNotifier(); StreamSubscription? _subscription; GridNotificationParser? _parser; - GridListener({required this.gridId}); + GridFieldsListener({required this.gridId}); void start() { _parser = GridNotificationParser( @@ -33,8 +33,8 @@ class GridListener { switch (ty) { case GridNotification.DidUpdateFields: result.fold( - (payload) => fieldsUpdateNotifier.value = left(RepeatedField.fromBuffer(payload).items), - (error) => fieldsUpdateNotifier.value = right(error), + (payload) => updateFieldsNotifier.value = left(RepeatedField.fromBuffer(payload).items), + (error) => updateFieldsNotifier.value = right(error), ); break; default: @@ -45,6 +45,6 @@ class GridListener { Future stop() async { _parser = null; await _subscription?.cancel(); - fieldsUpdateNotifier.dispose(); + updateFieldsNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart index 7f5417a396..a2f7438434 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart @@ -29,6 +29,9 @@ class SwitchFieldTypeBloc extends Bloc Log.error(err), ); }, + didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) { + emit(state.copyWith(typeOptionData: value.typeOptionData)); + }, ); }, ); @@ -43,6 +46,7 @@ class SwitchFieldTypeBloc extends Bloc { - NumberTypeOptionBloc() : super(NumberTypeOptionState.initial()) { + NumberTypeOptionBloc({required NumberTypeOption typeOption}) : super(NumberTypeOptionState.initial(typeOption)) { on( (event, emit) async { await event.map( initial: (_InitialField value) async {}, + didSelectFormat: (_DidSelectFormat value) { + state.typeOption.format = value.format; + emit(state); + }, ); }, ); @@ -28,12 +28,17 @@ class NumberTypeOptionBloc extends Bloc NumberTypeOptionState(); + factory NumberTypeOptionState.initial(NumberTypeOption typeOption) => NumberTypeOptionState( + typeOption: typeOption, + ); } 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 b155126a72..00f90e0bfc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -8,7 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:equatable/equatable.dart'; import 'grid_block_service.dart'; -import 'grid_listenr.dart'; +import 'field/grid_listenr.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -16,11 +16,11 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final View view; final GridService service; - late GridListener _gridListener; + late GridFieldsListener _fieldListener; late GridBlockService _blockService; GridBloc({required this.view, required this.service}) : super(GridState.initial()) { - _gridListener = GridListener(gridId: view.id); + _fieldListener = GridFieldsListener(gridId: view.id); on( (event, emit) async { @@ -34,10 +34,10 @@ class GridBloc extends Bloc { delete: (_Delete value) {}, rename: (_Rename value) {}, updateDesc: (_Desc value) {}, - rowsDidUpdate: (_RowsDidUpdate value) { + didReceiveRowUpdate: (_DidReceiveRowUpdate value) { emit(state.copyWith(rows: value.rows)); }, - fieldsDidUpdate: (_FieldsDidUpdate value) { + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(fields: value.fields)); }, ); @@ -47,19 +47,19 @@ class GridBloc extends Bloc { @override Future close() async { - await _gridListener.stop(); + await _fieldListener.stop(); await _blockService.stop(); return super.close(); } Future _initGrid(Emitter emit) async { - _gridListener.fieldsUpdateNotifier.addPublishListener((result) { + _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( - (fields) => add(GridEvent.fieldsDidUpdate(fields)), + (fields) => add(GridEvent.didReceiveFieldUpdate(fields)), (err) => Log.error(err), ); }); - _gridListener.start(); + _fieldListener.start(); await _loadGrid(emit); } @@ -72,7 +72,7 @@ class GridBloc extends Bloc { _blockService.blocksUpdateNotifier?.addPublishListener((result) { result.fold( - (blockMap) => add(GridEvent.rowsDidUpdate(_buildRows(blockMap))), + (blockMap) => add(GridEvent.didReceiveRowUpdate(_buildRows(blockMap))), (err) => Log.error('$err'), ); }); @@ -128,8 +128,8 @@ class GridEvent with _$GridEvent { const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.rowsDidUpdate(List rows) = _RowsDidUpdate; - const factory GridEvent.fieldsDidUpdate(List fields) = _FieldsDidUpdate; + const factory GridEvent.didReceiveRowUpdate(List rows) = _DidReceiveRowUpdate; + const factory GridEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 2bb78799f0..ac99eac67b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,5 +1,6 @@ import 'dart:collection'; +import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; @@ -17,7 +18,7 @@ typedef CellDataMap = HashMap; class RowBloc extends Bloc { final RowService rowService; final RowListener rowlistener; - final RowFieldListener fieldListener; + final GridFieldsListener fieldListener; RowBloc({required GridRowData rowData, required this.rowlistener}) : rowService = RowService( @@ -25,7 +26,7 @@ class RowBloc extends Bloc { blockId: rowData.blockId, rowId: rowData.rowId, ), - fieldListener = RowFieldListener( + fieldListener = GridFieldsListener( gridId: rowData.gridId, ), super(RowState.initial(rowData)) { @@ -65,8 +66,8 @@ class RowBloc extends Bloc { @override Future close() async { - await rowlistener.close(); - await fieldListener.close(); + await rowlistener.stop(); + await fieldListener.stop(); return super.close(); } @@ -89,7 +90,7 @@ class RowBloc extends Bloc { ); }); - fieldListener.updateFieldNotifier.addPublishListener((result) { + fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( (fields) => add(RowEvent.didReceiveFieldUpdate(fields)), (err) => Log.error(err), diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart index c5084f4164..011dbd8636 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart @@ -46,49 +46,10 @@ class RowListener { } } - Future close() async { + Future stop() async { _parser = null; await _subscription?.cancel(); updateCellNotifier.dispose(); updateRowNotifier.dispose(); } } - -class RowFieldListener { - final String gridId; - PublishNotifier updateFieldNotifier = PublishNotifier(); - StreamSubscription? _subscription; - GridNotificationParser? _parser; - - RowFieldListener({required this.gridId}); - - void start() { - _parser = GridNotificationParser( - id: gridId, - callback: (ty, result) { - _handleObservableType(ty, result); - }, - ); - - _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); - } - - void _handleObservableType(GridNotification ty, Either result) { - switch (ty) { - case GridNotification.DidUpdateFields: - result.fold( - (payload) => updateFieldNotifier.value = left(RepeatedField.fromBuffer(payload).items), - (error) => updateFieldNotifier.value = right(error), - ); - break; - default: - break; - } - } - - Future close() async { - _parser = null; - await _subscription?.cancel(); - updateFieldNotifier.dispose(); - } -} 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 e1c44c253b..984ed147a1 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/grid_service.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'; @@ -97,7 +96,6 @@ class _FlowyGridState extends State { child: ScrollConfiguration( behavior: const ScrollBehavior().copyWith(scrollbars: false), child: CustomScrollView( - shrinkWrap: true, physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index b8834cd213..a813a51dc0 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -30,28 +30,47 @@ class _GridRowWidgetState extends State { Widget build(BuildContext context) { return BlocProvider.value( value: _rowBloc, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), - onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, - ), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, ), ); + // return BlocProvider.value( + // value: _rowBloc, + // child: MouseRegion( + // cursor: SystemMouseCursors.click, + // onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + // onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + // child: BlocBuilder( + // buildWhen: (p, c) => p.rowHeight != c.rowHeight, + // builder: (context, state) { + // return SizedBox( + // height: _rowBloc.state.rowHeight, + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: const [ + // _RowLeading(), + // _RowCells(), + // _RowTrailing(), + // ], + // ), + // ); + // }, + // ), + // ), + // ); } @override diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index 6a7c6d05ef..dd477dd8bb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -52,7 +52,7 @@ class _CreateFieldPannelWidget extends StatelessWidget { child: BlocBuilder( builder: (context, state) { return state.field.fold( - () => const SizedBox(), + () => const SizedBox(width: 200), (field) => ListView( shrinkWrap: true, children: [ diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart index ce542b6760..cab5a51138 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart @@ -95,10 +95,10 @@ class _FieldNameTextField extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( - buildWhen: ((previous, current) => previous.editContext.gridField.name == current.editContext.gridField.name), + buildWhen: ((previous, current) => previous.fieldName == current.fieldName), builder: (context, state) { return FieldNameTextField( - name: state.editContext.gridField.name, + name: state.fieldName, errorText: state.errorText, onNameChanged: (newName) { context.read().add(EditFieldEvent.updateFieldName(newName)); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart index ddf5eb7660..a4ccc94a94 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart @@ -46,7 +46,7 @@ class FieldActionItem extends StatelessWidget { text: FlowyText.medium(action.title(), fontSize: 12), hoverColor: theme.hover, onTap: () { - action.run(context, fieldId); + action.run(context); onTap(); }, leftIcon: svg(action.iconName(), color: theme.iconColor), @@ -83,16 +83,16 @@ extension _FieldActionExtension on FieldAction { } } - void run(BuildContext context, String fieldId) { + void run(BuildContext context) { switch (this) { case FieldAction.hide: - context.read().add(EditFieldEvent.hideField(fieldId)); + context.read().add(const EditFieldEvent.hideField()); break; case FieldAction.duplicate: - context.read().add(EditFieldEvent.duplicateField(fieldId)); + context.read().add(const EditFieldEvent.duplicateField()); break; case FieldAction.delete: - context.read().add(EditFieldEvent.deleteField(fieldId)); + context.read().add(const EditFieldEvent.deleteField()); break; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index cd9adbd928..1fee89aecb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -11,12 +11,13 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'type_option/number.dart'; + typedef SelectFieldCallback = void Function(Field, Uint8List); class FieldTypeSwitcher extends StatelessWidget { @@ -40,8 +41,11 @@ class FieldTypeSwitcher extends StatelessWidget { ]; final builder = _makeTypeOptionBuild( - state.field.fieldType, - state.typeOptionData, + fieldType: state.field.fieldType, + typeOptionData: state.typeOptionData, + typeOptionDataCallback: (newTypeOptionData) { + context.read().add(SwitchFieldTypeEvent.didUpdateTypeOptionData(newTypeOptionData)); + }, ); final typeOptionWidget = builder.customWidget; @@ -77,7 +81,6 @@ class FieldTypeSwitcher extends StatelessWidget { } abstract class TypeOptionBuilder { - Uint8List? get typeOptionData; Widget? get customWidget; } @@ -85,7 +88,14 @@ abstract class TypeOptionWidget extends StatelessWidget { const TypeOptionWidget({Key? key}) : super(key: key); } -TypeOptionBuilder _makeTypeOptionBuild(FieldType fieldType, Uint8List typeOptionData) { +typedef TypeOptionData = Uint8List; +typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData); + +TypeOptionBuilder _makeTypeOptionBuild({ + required FieldType fieldType, + required TypeOptionData typeOptionData, + required TypeOptionDataCallback typeOptionDataCallback, +}) { switch (fieldType) { case FieldType.Checkbox: return CheckboxTypeOptionBuilder(typeOptionData); @@ -94,7 +104,7 @@ TypeOptionBuilder _makeTypeOptionBuild(FieldType fieldType, Uint8List typeOption case FieldType.MultiSelect: return MultiSelectTypeOptionBuilder(typeOptionData); case FieldType.Number: - return NumberTypeOptionBuilder(typeOptionData); + return NumberTypeOptionBuilder(typeOptionData, typeOptionDataCallback); case FieldType.RichText: return RichTextTypeOptionBuilder(typeOptionData); case FieldType.SingleSelect: @@ -107,46 +117,16 @@ TypeOptionBuilder _makeTypeOptionBuild(FieldType fieldType, Uint8List typeOption class RichTextTypeOptionBuilder extends TypeOptionBuilder { RichTextTypeOption typeOption; - RichTextTypeOptionBuilder(Uint8List typeOptionData) : typeOption = RichTextTypeOption.fromBuffer(typeOptionData); - - @override - Uint8List? get typeOptionData => typeOption.writeToBuffer(); + RichTextTypeOptionBuilder(TypeOptionData typeOptionData) : typeOption = RichTextTypeOption.fromBuffer(typeOptionData); @override Widget? get customWidget => null; } -class NumberTypeOptionBuilder extends TypeOptionBuilder { - NumberTypeOption typeOption; - - NumberTypeOptionBuilder(Uint8List typeOptionData) : typeOption = NumberTypeOption.fromBuffer(typeOptionData); - - @override - Uint8List? get typeOptionData => typeOption.writeToBuffer(); - - @override - Widget? get customWidget => const NumberTypeOptionWidget(); -} - -class NumberTypeOptionWidget extends TypeOptionWidget { - const NumberTypeOptionWidget({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(), - child: Container(height: 30, color: Colors.green), - ); - } -} - class DateTypeOptionBuilder extends TypeOptionBuilder { DateTypeOption typeOption; - DateTypeOptionBuilder(Uint8List typeOptionData) : typeOption = DateTypeOption.fromBuffer(typeOptionData); - - @override - Uint8List? get typeOptionData => typeOption.writeToBuffer(); + DateTypeOptionBuilder(TypeOptionData typeOptionData) : typeOption = DateTypeOption.fromBuffer(typeOptionData); @override Widget? get customWidget => const DateTypeOptionWidget(); @@ -167,10 +147,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { class CheckboxTypeOptionBuilder extends TypeOptionBuilder { CheckboxTypeOption typeOption; - CheckboxTypeOptionBuilder(Uint8List typeOptionData) : typeOption = CheckboxTypeOption.fromBuffer(typeOptionData); - - @override - Uint8List? get typeOptionData => throw UnimplementedError(); + CheckboxTypeOptionBuilder(TypeOptionData typeOptionData) : typeOption = CheckboxTypeOption.fromBuffer(typeOptionData); @override Widget? get customWidget => null; @@ -179,12 +156,9 @@ class CheckboxTypeOptionBuilder extends TypeOptionBuilder { class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { SingleSelectTypeOption typeOption; - SingleSelectTypeOptionBuilder(Uint8List typeOptionData) + SingleSelectTypeOptionBuilder(TypeOptionData typeOptionData) : typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData); - @override - Uint8List? get typeOptionData => typeOption.writeToBuffer(); - @override Widget? get customWidget => const SingleSelectTypeOptionWidget(); } @@ -204,12 +178,9 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget { class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { MultiSelectTypeOption typeOption; - MultiSelectTypeOptionBuilder(Uint8List typeOptionData) + MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData) : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); - @override - Uint8List? get typeOptionData => typeOption.writeToBuffer(); - @override Widget? get customWidget => const MultiSelectTypeOptionWidget(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart new file mode 100644 index 0000000000..6e07fec904 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -0,0 +1,123 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'create_field_pannel.dart'; +import 'grid_header_cell.dart'; + +class GridHeaderDelegate extends SliverPersistentHeaderDelegate { + final String gridId; + final List fields; + + GridHeaderDelegate({required this.gridId, required this.fields}); + + @override + Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + return GridHeader(gridId: gridId, fields: fields, key: ObjectKey(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; + final String gridId; + const GridHeader({required this.gridId, required this.fields, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocProvider( + create: (context) { + final bloc = getIt(param1: gridId, param2: fields); + bloc.add(const GridHeaderEvent.initial()); + return bloc; + }, + child: BlocBuilder( + builder: (context, state) { + final cells = state.fields.map( + (field) => GridHeaderCell( + GridFieldData(gridId: gridId, field: field), + ), + ); + + final row = Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _HeaderLeading(), + ...cells, + _HeaderTrailing(gridId: gridId), + ], + ); + + return Container(color: theme.surface, child: row); + }, + ), + ); + } +} + +class _HeaderLeading extends StatelessWidget { + const _HeaderLeading({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: GridSize.leadingHeaderPadding, + ); + } +} + +class _HeaderTrailing extends StatelessWidget { + final String gridId; + const _HeaderTrailing({required this.gridId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return Container( + width: GridSize.trailHeaderPadding, + decoration: BoxDecoration( + border: Border(top: borderSide, bottom: borderSide), + ), + padding: GridSize.headerContentInsets, + child: CreateFieldButton(gridId: gridId), + ); + } +} + +class CreateFieldButton extends StatelessWidget { + final String gridId; + const CreateFieldButton({required this.gridId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: const FlowyText.medium('New column', fontSize: 12), + hoverColor: theme.hover, + onTap: () => CreateFieldPannel(gridId: gridId).show(context, gridId), + leftIcon: svg("home/add"), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart new file mode 100755 index 0000000000..5e5dc5f4fd --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart @@ -0,0 +1,36 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'edit_field_pannel.dart'; + +class GridHeaderCell extends StatelessWidget { + final GridFieldData fieldData; + const GridHeaderCell(this.fieldData, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final button = FlowyButton( + hoverColor: theme.hover, + onTap: () => EditFieldPannel.show(context, fieldData), + rightIcon: svg("editor/details", color: theme.iconColor), + text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), + ); + + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); + + return Container( + width: fieldData.field.width.toDouble(), + decoration: decoration, + padding: GridSize.headerContentInsets, + child: button, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart new file mode 100644 index 0000000000..f7016510b7 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -0,0 +1,165 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/number_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart' hide NumberFormat; +import 'package:app_flowy/generated/locale_keys.g.dart'; + +class NumberTypeOptionBuilder extends TypeOptionBuilder { + NumberTypeOption typeOption; + TypeOptionDataCallback typeOptionDataCallback; + + NumberTypeOptionBuilder( + TypeOptionData typeOptionData, + this.typeOptionDataCallback, + ) : typeOption = NumberTypeOption.fromBuffer(typeOptionData); + + @override + Widget? get customWidget => NumberTypeOptionWidget( + typeOption: typeOption, + updateCallback: typeOptionDataCallback, + ); +} + +class NumberTypeOptionWidget extends TypeOptionWidget { + final TypeOptionDataCallback updateCallback; + final NumberTypeOption typeOption; + const NumberTypeOptionWidget({required this.typeOption, required this.updateCallback, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocProvider( + create: (context) => getIt(param1: typeOption), + child: SizedBox( + height: 36, + child: BlocConsumer( + listener: (context, state) => updateCallback(state.typeOption.writeToBuffer()), + builder: (context, state) { + return FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_numberFormat.tr(), fontSize: 12), + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + hoverColor: theme.hover, + onTap: () { + NumberFormatList.show(context, (format) { + context.read().add(NumberTypeOptionEvent.didSelectFormat(format)); + }); + }, + rightIcon: svg("grid/more", color: theme.iconColor), + ); + }, + ), + ), + ); + } +} + +typedef _SelectNumberFormatCallback = Function(NumberFormat format); + +class NumberFormatList extends StatelessWidget { + final _SelectNumberFormatCallback onSelected; + const NumberFormatList({required this.onSelected, Key? key}) : super(key: key); + + static void show(BuildContext context, _SelectNumberFormatCallback onSelected) { + final list = NumberFormatList(onSelected: onSelected); + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: list, + constraints: BoxConstraints.loose(const Size(140, 300)), + ), + identifier: list.identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.leftWithCenterAligned, + style: FlowyOverlayStyle(blur: false), + anchorOffset: const Offset(-20, 0), + ); + } + + @override + Widget build(BuildContext context) { + final formatItems = NumberFormat.values.map((format) { + return NumberFormatItem( + format: format, + onSelected: (format) { + onSelected(format); + FlowyOverlay.of(context).remove(identifier()); + }); + }).toList(); + + return ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return const VSpace(10); + }, + itemCount: formatItems.length, + itemBuilder: (BuildContext context, int index) { + return formatItems[index]; + }, + ); + } + + String identifier() { + return toString(); + } +} + +class NumberFormatItem extends StatelessWidget { + final NumberFormat format; + final Function(NumberFormat format) onSelected; + const NumberFormatItem({required this.format, required this.onSelected, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: 26, + child: FlowyButton( + text: FlowyText.medium(format.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () => onSelected(format), + leftIcon: svg(format.iconName(), color: theme.iconColor), + ), + ); + } +} + +extension NumberFormatExtension on NumberFormat { + String title() { + switch (this) { + case NumberFormat.CNY: + return "Yen"; + case NumberFormat.EUR: + return "Euro"; + case NumberFormat.Number: + return "Numbers"; + case NumberFormat.USD: + return "US Dollar"; + default: + throw UnimplementedError; + } + } + + String iconName() { + switch (this) { + case NumberFormat.CNY: + return "grid/field/yen"; + case NumberFormat.EUR: + return "grid/field/euro"; + case NumberFormat.Number: + return "grid/field/numbers"; + case NumberFormat.USD: + return "grid/field/us_dollar"; + default: + throw UnimplementedError; + } + } +} From d2080a6c03707953638f3c639c3a00fddd210819 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 28 Mar 2022 22:47:30 +0800 Subject: [PATCH 067/179] chore: date field --- .../app_flowy/assets/translations/en.json | 10 +- .../app_flowy/lib/startup/deps_resolver.dart | 9 +- .../grid/field/switch_field_type_bloc.dart | 20 +- .../grid/field/type_option/date_bloc.dart | 28 ++- .../grid/field/type_option/number_bloc.dart | 4 +- .../plugins/grid/src/layout/sizes.dart | 7 + .../widgets/header/create_field_pannel.dart | 2 - .../widgets/header/field_tyep_switcher.dart | 201 +++++++-------- .../src/widgets/header/field_type_list.dart | 13 +- .../src/widgets/header/type_option/date.dart | 229 ++++++++++++++++++ .../widgets/header/type_option/number.dart | 58 ++--- .../widgets/header/type_option/selection.dart | 50 ++++ .../lib/src/flowy_overlay/flowy_overlay.dart | 4 +- 13 files changed, 458 insertions(+), 177 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 1031265da1..0fe9008ee6 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -155,7 +155,15 @@ "numberFieldName": "Numbers", "singleSelectFieldName": "Select", "multiSelectFieldName": "Multiselect", - "numberFormat": " Number format" + "numberFormat": " Number format", + "dateFormat": " Date format", + "dateFormatFriendly": "Month Day,Year", + "dateFormatISO": "Year-Month-Day", + "dateFormatLocal": "Month/Month/Day", + "dateFormatUS": "Month/Month/Day", + "timeFormat": " Time format", + "timeFormatTwelveHour": "12 hour", + "timeFormatTwentyFourHour": "24 hour" } } } diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index e277bc6a20..5d78cbdf2a 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -18,6 +18,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -210,16 +211,16 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (context, _) => SwitchFieldTypeBloc(context), + getIt.registerFactoryParam( + (context, _) => FieldTypeSwitchBloc(context), ); getIt.registerFactory( () => SelectionTypeOptionBloc(), ); - getIt.registerFactory( - () => DateTypeOptionBloc(), + getIt.registerFactoryParam( + (typeOption, _) => DateTypeOptionBloc(typeOption: typeOption), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart index a2f7438434..ba8371c3a3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart @@ -9,9 +9,9 @@ import 'field_service.dart'; part 'switch_field_type_bloc.freezed.dart'; -class SwitchFieldTypeBloc extends Bloc { - SwitchFieldTypeBloc(SwitchFieldContext editContext) : super(SwitchFieldTypeState.initial(editContext)) { - on( +class FieldTypeSwitchBloc extends Bloc { + FieldTypeSwitchBloc(SwitchFieldContext editContext) : super(FieldTypeSwitchState.initial(editContext)) { + on( (event, emit) async { await event.map( toFieldType: (_ToFieldType value) async { @@ -44,20 +44,20 @@ class SwitchFieldTypeBloc extends Bloc SwitchFieldTypeState( + factory FieldTypeSwitchState.initial(SwitchFieldContext switchContext) => FieldTypeSwitchState( gridId: switchContext.gridId, field: switchContext.field, typeOptionData: Uint8List.fromList(switchContext.typeOptionData), diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart index 78b22b078b..e2e7f2f0e2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -1,20 +1,23 @@ -import 'dart:typed_data'; - -import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'package:dartz/dartz.dart'; part 'date_bloc.freezed.dart'; class DateTypeOptionBloc extends Bloc { - DateTypeOptionBloc() : super(DateTypeOptionState.initial()) { + DateTypeOptionBloc({required DateTypeOption typeOption}) : super(DateTypeOptionState.initial(typeOption)) { on( (event, emit) async { - await event.map( - initial: (_InitialField value) async {}, + event.map( + didSelectDateFormat: (_DidSelectDateFormat value) { + state.typeOption.dateFormat = value.format; + emit(state); + }, + didSelectTimeFormat: (_DidSelectTimeFormat value) { + state.typeOption.timeFormat = value.format; + emit(state); + }, ); }, ); @@ -28,12 +31,15 @@ class DateTypeOptionBloc extends Bloc @freezed class DateTypeOptionEvent with _$DateTypeOptionEvent { - const factory DateTypeOptionEvent.initial(Uint8List? typeOptionData) = _InitialField; + const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) = _DidSelectDateFormat; + const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) = _DidSelectTimeFormat; } @freezed class DateTypeOptionState with _$DateTypeOptionState { - const factory DateTypeOptionState() = _DateTypeOptionState; + const factory DateTypeOptionState({ + required DateTypeOption typeOption, + }) = _DateTypeOptionState; - factory DateTypeOptionState.initial() => DateTypeOptionState(); + factory DateTypeOptionState.initial(DateTypeOption typeOption) => DateTypeOptionState(typeOption: typeOption); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart index 5b63a7aee4..a396454671 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart @@ -9,8 +9,7 @@ class NumberTypeOptionBloc extends Bloc( (event, emit) async { - await event.map( - initial: (_InitialField value) async {}, + event.map( didSelectFormat: (_DidSelectFormat value) { state.typeOption.format = value.format; emit(state); @@ -28,7 +27,6 @@ class NumberTypeOptionBloc extends Bloc 140 * scale; static double get headerContainerPadding => 0 * scale; static double get cellContentPadding => 10 * scale; + static double get typeOptionItemHeight => 30 * scale; + static double get typeOptionSeparatorHeight => 6 * scale; // static EdgeInsets get headerContentInsets => EdgeInsets.symmetric( @@ -26,6 +28,11 @@ class GridSize { vertical: GridSize.cellContentPadding, ); + static EdgeInsets get typeOptionContentInsets => const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ); + static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( 0, GridSize.headerContainerPadding, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index dd477dd8bb..8b2b74d9ae 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -4,7 +4,6 @@ import 'package:app_flowy/workspace/application/grid/field/switch_field_type_blo import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_name_input.dart'; @@ -61,7 +60,6 @@ class _CreateFieldPannelWidget extends StatelessWidget { const _FieldNameTextField(), const VSpace(10), _FieldTypeSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)), - const VSpace(10), ], ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index 1fee89aecb..6e03b4243d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -1,26 +1,29 @@ import 'dart:typed_data'; -import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; + import 'type_option/number.dart'; typedef SelectFieldCallback = void Function(Field, Uint8List); -class FieldTypeSwitcher extends StatelessWidget { +class FieldTypeSwitcher extends StatefulWidget { final SwitchFieldContext switchContext; final SelectFieldCallback onSelected; @@ -30,25 +33,27 @@ class FieldTypeSwitcher extends StatelessWidget { Key? key, }) : super(key: key); + @override + State createState() => _FieldTypeSwitcherState(); +} + +class _FieldTypeSwitcherState extends State { + String? currentOverlayIdentifier; + @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: switchContext), - child: BlocBuilder( + create: (context) => getIt(param1: widget.switchContext), + child: BlocBuilder( builder: (context, state) { - List children = [ - _switchFieldTypeButton(context, state.field), - ]; + List children = [_switchFieldTypeButton(context, state.field)]; - final builder = _makeTypeOptionBuild( + final typeOptionWidget = _typeOptionWidget( + context: context, fieldType: state.field.fieldType, - typeOptionData: state.typeOptionData, - typeOptionDataCallback: (newTypeOptionData) { - context.read().add(SwitchFieldTypeEvent.didUpdateTypeOptionData(newTypeOptionData)); - }, + data: state.typeOptionData, ); - final typeOptionWidget = builder.customWidget; if (typeOptionWidget != null) { children.add(typeOptionWidget); } @@ -65,53 +70,100 @@ class FieldTypeSwitcher extends StatelessWidget { Widget _switchFieldTypeButton(BuildContext context, Field field) { final theme = context.watch(); return SizedBox( - height: 36, + height: GridSize.typeOptionItemHeight, child: FlowyButton( text: FlowyText.medium(field.fieldType.title(), fontSize: 12), padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), hoverColor: theme.hover, - onTap: () => FieldTypeList.show(context, (fieldType) { - context.read().add(SwitchFieldTypeEvent.toFieldType(fieldType)); - }), + onTap: () { + final list = FieldTypeList(onSelectField: (fieldType) { + context.read().add(FieldTypeSwitchEvent.toFieldType(fieldType)); + }); + _showOverlay(context, FieldTypeList.identifier(), list); + }, leftIcon: svg(field.fieldType.iconName(), color: theme.iconColor), rightIcon: svg("grid/more", color: theme.iconColor), ), ); } + + Widget? _typeOptionWidget({ + required BuildContext context, + required FieldType fieldType, + required TypeOptionData data, + }) { + final delegate = TypeOptionOperationDelegate( + didUpdateTypeOptionData: (data) { + context.read().add(FieldTypeSwitchEvent.didUpdateTypeOptionData(data)); + }, + requireToShowOverlay: _showOverlay, + ); + final builder = _makeTypeOptionBuild(fieldType: fieldType, data: data, delegate: delegate); + return builder.customWidget; + } + + void _showOverlay(BuildContext context, String identifier, Widget child) { + if (currentOverlayIdentifier != null) { + FlowyOverlay.of(context).remove(currentOverlayIdentifier!); + } + + currentOverlayIdentifier = identifier; + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: child, + constraints: BoxConstraints.loose(const Size(240, 400)), + ), + identifier: identifier, + anchorContext: context, + anchorDirection: AnchorDirection.leftWithCenterAligned, + style: FlowyOverlayStyle(blur: false), + anchorOffset: const Offset(-20, 0), + ); + } } abstract class TypeOptionBuilder { Widget? get customWidget; } +TypeOptionBuilder _makeTypeOptionBuild({ + required FieldType fieldType, + required TypeOptionData data, + required TypeOptionOperationDelegate delegate, +}) { + switch (fieldType) { + case FieldType.Checkbox: + return CheckboxTypeOptionBuilder(data); + case FieldType.DateTime: + return DateTypeOptionBuilder(data, delegate); + case FieldType.MultiSelect: + return MultiSelectTypeOptionBuilder(data); + case FieldType.Number: + return NumberTypeOptionBuilder(data, delegate); + case FieldType.RichText: + return RichTextTypeOptionBuilder(data); + case FieldType.SingleSelect: + return SingleSelectTypeOptionBuilder(data); + default: + throw UnimplementedError; + } +} + abstract class TypeOptionWidget extends StatelessWidget { const TypeOptionWidget({Key? key}) : super(key: key); } typedef TypeOptionData = Uint8List; typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData); +typedef ShowOverlayCallback = void Function(BuildContext anchorContext, String overlayIdentifier, Widget child); -TypeOptionBuilder _makeTypeOptionBuild({ - required FieldType fieldType, - required TypeOptionData typeOptionData, - required TypeOptionDataCallback typeOptionDataCallback, -}) { - switch (fieldType) { - case FieldType.Checkbox: - return CheckboxTypeOptionBuilder(typeOptionData); - case FieldType.DateTime: - return DateTypeOptionBuilder(typeOptionData); - case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder(typeOptionData); - case FieldType.Number: - return NumberTypeOptionBuilder(typeOptionData, typeOptionDataCallback); - case FieldType.RichText: - return RichTextTypeOptionBuilder(typeOptionData); - case FieldType.SingleSelect: - return SingleSelectTypeOptionBuilder(typeOptionData); - default: - throw UnimplementedError; - } +class TypeOptionOperationDelegate { + TypeOptionDataCallback didUpdateTypeOptionData; + ShowOverlayCallback requireToShowOverlay; + TypeOptionOperationDelegate({ + required this.didUpdateTypeOptionData, + required this.requireToShowOverlay, + }); } class RichTextTypeOptionBuilder extends TypeOptionBuilder { @@ -123,27 +175,6 @@ class RichTextTypeOptionBuilder extends TypeOptionBuilder { Widget? get customWidget => null; } -class DateTypeOptionBuilder extends TypeOptionBuilder { - DateTypeOption typeOption; - - DateTypeOptionBuilder(TypeOptionData typeOptionData) : typeOption = DateTypeOption.fromBuffer(typeOptionData); - - @override - Widget? get customWidget => const DateTypeOptionWidget(); -} - -class DateTypeOptionWidget extends TypeOptionWidget { - const DateTypeOptionWidget({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(), - child: Container(height: 80, color: Colors.red), - ); - } -} - class CheckboxTypeOptionBuilder extends TypeOptionBuilder { CheckboxTypeOption typeOption; @@ -152,47 +183,3 @@ class CheckboxTypeOptionBuilder extends TypeOptionBuilder { @override Widget? get customWidget => null; } - -class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { - SingleSelectTypeOption typeOption; - - SingleSelectTypeOptionBuilder(TypeOptionData typeOptionData) - : typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData); - - @override - Widget? get customWidget => const SingleSelectTypeOptionWidget(); -} - -class SingleSelectTypeOptionWidget extends TypeOptionWidget { - const SingleSelectTypeOptionWidget({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(), - child: Container(height: 100, color: Colors.yellow), - ); - } -} - -class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { - MultiSelectTypeOption typeOption; - - MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData) - : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); - - @override - Widget? get customWidget => const MultiSelectTypeOptionWidget(); -} - -class MultiSelectTypeOptionWidget extends TypeOptionWidget { - const MultiSelectTypeOptionWidget({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(), - child: Container(height: 100, color: Colors.blue), - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index 25481fce09..dfc5c007c6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -19,12 +19,13 @@ class FieldTypeList extends StatelessWidget { static void show(BuildContext context, SelectFieldCallback onSelectField) { final list = FieldTypeList(onSelectField: onSelectField); + FieldTypeList.hide(context); FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: list, constraints: BoxConstraints.loose(const Size(140, 300)), ), - identifier: list.identifier(), + identifier: FieldTypeList.identifier(), anchorContext: context, anchorDirection: AnchorDirection.leftWithCenterAligned, style: FlowyOverlayStyle(blur: false), @@ -32,6 +33,10 @@ class FieldTypeList extends StatelessWidget { ); } + static void hide(BuildContext context) { + FlowyOverlay.of(context).remove(FieldTypeList.identifier()); + } + @override Widget build(BuildContext context) { final cells = FieldType.values.map((fieldType) { @@ -39,7 +44,7 @@ class FieldTypeList extends StatelessWidget { fieldType: fieldType, onSelectField: (fieldType) { onSelectField(fieldType); - FlowyOverlay.of(context).remove(identifier()); + FlowyOverlay.of(context).remove(FieldTypeList.identifier()); }, ); }).toList(); @@ -58,8 +63,8 @@ class FieldTypeList extends StatelessWidget { ); } - String identifier() { - return toString(); + static String identifier() { + return (FieldTypeList).toString(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart new file mode 100644 index 0000000000..493ab0e02e --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -0,0 +1,229 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/date_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:easy_localization/easy_localization.dart' hide DateFormat; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DateTypeOptionBuilder extends TypeOptionBuilder { + DateTypeOption typeOption; + TypeOptionOperationDelegate delegate; + + DateTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate) + : typeOption = DateTypeOption.fromBuffer(typeOptionData); + + @override + Widget? get customWidget => DateTypeOptionWidget( + typeOption: typeOption, + operationDelegate: delegate, + ); +} + +class DateTypeOptionWidget extends TypeOptionWidget { + final DateTypeOption typeOption; + final TypeOptionOperationDelegate operationDelegate; + const DateTypeOptionWidget({required this.typeOption, required this.operationDelegate, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: typeOption), + child: BlocConsumer( + listener: (context, state) => operationDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), + builder: (context, state) { + return Column(children: [ + _dateFormatButton(context), + _timeFormatButton(context), + ]); + }, + ), + ); + } + + Widget _dateFormatButton(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_dateFormat.tr(), fontSize: 12), + padding: GridSize.typeOptionContentInsets, + hoverColor: theme.hover, + onTap: () { + final list = DateFormatList(onSelected: (format) { + context.read().add(DateTypeOptionEvent.didSelectDateFormat(format)); + }); + operationDelegate.requireToShowOverlay(context, list.identifier(), list); + }, + rightIcon: svg("grid/more", color: theme.iconColor), + ), + ); + } + + Widget _timeFormatButton(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_timeFormat.tr(), fontSize: 12), + padding: GridSize.typeOptionContentInsets, + hoverColor: theme.hover, + onTap: () { + final list = TimeFormatList(onSelected: (format) { + context.read().add(DateTypeOptionEvent.didSelectTimeFormat(format)); + }); + operationDelegate.requireToShowOverlay(context, list.identifier(), list); + }, + rightIcon: svg("grid/more", color: theme.iconColor), + ), + ); + } +} + +class DateFormatList extends StatelessWidget { + final Function(DateFormat format) onSelected; + const DateFormatList({required this.onSelected, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final formatItems = DateFormat.values.map((format) { + return DateFormatItem( + dateFormat: format, + onSelected: (format) { + onSelected(format); + FlowyOverlay.of(context).remove(identifier()); + }); + }).toList(); + + return SizedBox( + width: 180, + child: ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: formatItems.length, + itemBuilder: (BuildContext context, int index) { + return formatItems[index]; + }, + ), + ); + } + + String identifier() { + return toString(); + } +} + +class DateFormatItem extends StatelessWidget { + final DateFormat dateFormat; + final Function(DateFormat format) onSelected; + const DateFormatItem({required this.dateFormat, required this.onSelected, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(dateFormat.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () => onSelected(dateFormat), + ), + ); + } +} + +extension DateFormatExtension on DateFormat { + String title() { + switch (this) { + case DateFormat.Friendly: + return LocaleKeys.grid_field_dateFormatFriendly.tr(); + case DateFormat.ISO: + return LocaleKeys.grid_field_dateFormatISO.tr(); + case DateFormat.Local: + return LocaleKeys.grid_field_dateFormatLocal.tr(); + case DateFormat.US: + return LocaleKeys.grid_field_dateFormatUS.tr(); + default: + throw UnimplementedError; + } + } +} + +class TimeFormatList extends StatelessWidget { + final Function(TimeFormat format) onSelected; + const TimeFormatList({required this.onSelected, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final formatItems = TimeFormat.values.map((format) { + return TimeFormatItem( + timeFormat: format, + onSelected: (format) { + onSelected(format); + FlowyOverlay.of(context).remove(identifier()); + }); + }).toList(); + + return SizedBox( + width: 120, + child: ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: formatItems.length, + itemBuilder: (BuildContext context, int index) { + return formatItems[index]; + }, + ), + ); + } + + String identifier() { + return toString(); + } +} + +class TimeFormatItem extends StatelessWidget { + final TimeFormat timeFormat; + final Function(TimeFormat format) onSelected; + const TimeFormatItem({required this.timeFormat, required this.onSelected, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(timeFormat.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () => onSelected(timeFormat), + ), + ); + } +} + +extension TimeFormatExtension on TimeFormat { + String title() { + switch (this) { + case TimeFormat.TwelveHour: + return LocaleKeys.grid_field_timeFormatTwelveHour.tr(); + case TimeFormat.TwentyFourHour: + return LocaleKeys.grid_field_timeFormatTwentyFourHour.tr(); + default: + throw UnimplementedError; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index f7016510b7..6aeb73ac48 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/number_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -15,24 +16,24 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; class NumberTypeOptionBuilder extends TypeOptionBuilder { NumberTypeOption typeOption; - TypeOptionDataCallback typeOptionDataCallback; + TypeOptionOperationDelegate delegate; NumberTypeOptionBuilder( TypeOptionData typeOptionData, - this.typeOptionDataCallback, + this.delegate, ) : typeOption = NumberTypeOption.fromBuffer(typeOptionData); @override Widget? get customWidget => NumberTypeOptionWidget( typeOption: typeOption, - updateCallback: typeOptionDataCallback, + operationDelegate: delegate, ); } class NumberTypeOptionWidget extends TypeOptionWidget { - final TypeOptionDataCallback updateCallback; + final TypeOptionOperationDelegate operationDelegate; final NumberTypeOption typeOption; - const NumberTypeOptionWidget({required this.typeOption, required this.updateCallback, Key? key}) : super(key: key); + const NumberTypeOptionWidget({required this.typeOption, required this.operationDelegate, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -40,18 +41,19 @@ class NumberTypeOptionWidget extends TypeOptionWidget { return BlocProvider( create: (context) => getIt(param1: typeOption), child: SizedBox( - height: 36, + height: GridSize.typeOptionItemHeight, child: BlocConsumer( - listener: (context, state) => updateCallback(state.typeOption.writeToBuffer()), + listener: (context, state) => operationDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), builder: (context, state) { return FlowyButton( text: FlowyText.medium(LocaleKeys.grid_field_numberFormat.tr(), fontSize: 12), - padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + padding: GridSize.typeOptionContentInsets, hoverColor: theme.hover, onTap: () { - NumberFormatList.show(context, (format) { + final list = NumberFormatList(onSelected: (format) { context.read().add(NumberTypeOptionEvent.didSelectFormat(format)); }); + operationDelegate.requireToShowOverlay(context, list.identifier(), list); }, rightIcon: svg("grid/more", color: theme.iconColor), ); @@ -68,21 +70,6 @@ class NumberFormatList extends StatelessWidget { final _SelectNumberFormatCallback onSelected; const NumberFormatList({required this.onSelected, Key? key}) : super(key: key); - static void show(BuildContext context, _SelectNumberFormatCallback onSelected) { - final list = NumberFormatList(onSelected: onSelected); - FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer( - child: list, - constraints: BoxConstraints.loose(const Size(140, 300)), - ), - identifier: list.identifier(), - anchorContext: context, - anchorDirection: AnchorDirection.leftWithCenterAligned, - style: FlowyOverlayStyle(blur: false), - anchorOffset: const Offset(-20, 0), - ); - } - @override Widget build(BuildContext context) { final formatItems = NumberFormat.values.map((format) { @@ -94,16 +81,19 @@ class NumberFormatList extends StatelessWidget { }); }).toList(); - return ListView.separated( - shrinkWrap: true, - controller: ScrollController(), - separatorBuilder: (context, index) { - return const VSpace(10); - }, - itemCount: formatItems.length, - itemBuilder: (BuildContext context, int index) { - return formatItems[index]; - }, + return SizedBox( + width: 120, + child: ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: formatItems.length, + itemBuilder: (BuildContext context, int index) { + return formatItems[index]; + }, + ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart new file mode 100644 index 0000000000..b5737fd219 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart @@ -0,0 +1,50 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/selection_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { + SingleSelectTypeOption typeOption; + + SingleSelectTypeOptionBuilder(TypeOptionData typeOptionData) + : typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData); + + @override + Widget? get customWidget => const SingleSelectTypeOptionWidget(); +} + +class SingleSelectTypeOptionWidget extends TypeOptionWidget { + const SingleSelectTypeOptionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(), + child: Container(height: 100, color: Colors.yellow), + ); + } +} + +class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { + MultiSelectTypeOption typeOption; + + MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData) + : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); + + @override + Widget? get customWidget => const MultiSelectTypeOptionWidget(); +} + +class MultiSelectTypeOptionWidget extends TypeOptionWidget { + const MultiSelectTypeOptionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(), + child: Container(height: 100, color: Colors.blue), + ); + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 26760dc411..651971d17f 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -182,7 +182,9 @@ class FlowyOverlayState extends State { void remove(String identifier) { setState(() { final index = _overlayList.indexWhere((ele) => ele.value2 == identifier); - _overlayList.removeAt(index).value3?.didRemove(); + if (index != -1) { + _overlayList.removeAt(index).value3?.didRemove(); + } }); } From f829c63bd25ead163b65b0653ab7df5b10d55c58 Mon Sep 17 00:00:00 2001 From: hasanbeder Date: Mon, 28 Feb 2022 03:24:12 +0300 Subject: [PATCH 068/179] feat: Turkish Language Added --- .../app_flowy/assets/translations/tr-TR.json | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 frontend/app_flowy/assets/translations/tr-TR.json diff --git a/frontend/app_flowy/assets/translations/tr-TR.json b/frontend/app_flowy/assets/translations/tr-TR.json new file mode 100644 index 0000000000..c83cace0a7 --- /dev/null +++ b/frontend/app_flowy/assets/translations/tr-TR.json @@ -0,0 +1,145 @@ +{ + "appName": "AppFlowy", + "defaultUsername": "Ben", + "welcomeText": "@:appName'e Hoş Geldiniz!", + "githubStarText": "GitHub Yıldızı!", + "subscribeNewsletterText": "Bültene Abone Ol", + "letsGoButtonText": "Hadi başlayalım.", + "title": "Başlık", + "signUp": { + "buttonText": "Kayıt Ol", + "title": "@:appName'e kaydolun.", + "getStartedText": "başlayalım", + "emptyPasswordError": "Parola boş olamaz", + "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz", + "unmatchedPasswordError": "Parolalar eşleşmiyor", + "alreadyHaveAnAccount": "Zaten hesabınız var mı?", + "emailHint": "E-Posta", + "passwordHint": "Parola", + "repeatPasswordHint": "Tekrar parola" + }, + "signIn": { + "loginTitle": "@:appName oturum aç", + "loginButtonText": "Giriş", + "buttonText": "Oturum Aç", + "forgotPassword": "Parolanızı mı Unuttunuz?", + "emailHint": "E-Posta", + "passwordHint": "Parola", + "dontHaveAnAccount": "Hesabınız yok mu?", + "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz", + "unmatchedPasswordError": "Parolalar eşleşmiyor" + }, + "workspace": { + "create": "Çalışma alanı oluştur", + "hint": "Çalışma alanı", + "notFoundError": "Çalışma alanı bulunamadı" + }, + "shareAction": { + "buttonText": "Paylaş", + "workInProgress": "Yakında", + "markdown": "Markdown", + "copyLink": "Link'i Kopyala" + }, + "disclosureAction": { + "rename": "Yeniden adlandır", + "delete": "Sil", + "duplicate": "Çoğalt" + }, + "blankPageTitle": "Boş sayfa", + "newPageText": "Yeni sayfa", + "trash": { + "text": "Çöp", + "restoreAll": "Geri Yükle", + "deleteAll": "Sil", + "pageHeader": { + "fileName": "Dosya adı", + "lastModified": "Son Değiştirme", + "created": "Oluşturuldu" + } + }, + "deletePagePrompt": { + "text": "Bu sayfa Çöp Kutusu'nda", + "restore": "Sayfayı geri yükle", + "deletePermanent": "Kalıcı olarak sil" + }, + "dialogCreatePageNameHint": "Sayfa adı", + "questionBubble": { + "whatsNew": "Yeni ne var?", + "help": "Yardım & Destek", + "debug": { + "name": "Hata Ayıklama", + "success": "Hata ayıklama bilgileri panoya kopyalandı!", + "fail": "Hata ayıklama bilgileri panoya kopyalanamıyor" + } + }, + "menuAppHeader": { + "addPageTooltip": "Yeni bir sayfa ekleyin", + "defaultNewPageName": "Başlıksız", + "renameDialog": "Yeniden adlandır" + }, + "toolbar": { + "undo": "Geri", + "redo": "İleri", + "bold": "Kalın", + "italic": "İtalik", + "underline": "Altı Çizili", + "strike": "Üstü Çizili", + "numList": "Numaralı Liste", + "bulletList": "Madde İşaretli Liste", + "checkList": "Yapılacaklar Listesi", + "inlineCode": "Kod", + "quote": "Alıntı", + "header": "Başlık", + "highlight": "Vurgu" + }, + "tooltip": { + "lightMode": "Aydınlık Mod'a Geç", + "darkMode": "Karanlık Mod'a Geç" + }, + "contactsPage": { + "title": "İletişim", + "whatsHappening": "Bu hafta neler var?", + "addContact": "Kişi Ekle", + "editContact": "Kişiyi Düzenle" + }, + "button": { + "OK": "TAMAM", + "Cancel": "İptal", + "signIn": "Oturum Aç", + "signOut": "Oturum Kapat", + "complete": "Tamamlandı", + "save": "Kaydet" + }, + "label": { + "welcome": "Merhaba!", + "firstName": "Ad", + "middleName": "İkinci Ad", + "lastName": "Soyad", + "stepX": "Aşama {X}" + }, + "oAuth": { + "err": { + "failedTitle": "Hesabınıza bağlanılamıyor.", + "failedMsg": "Lütfen, tarayıcınızda oturum açma işlemini tamamladığınızdan emin olun." + }, + "google": { + "title": "GOOGLE OTURUM AÇMA", + "instruction1": "Google Kişilerinizi içe aktarmak için web tarayıcınızı kullanarak bu uygulamaya izin vermeniz gerekir.", + "instruction2": "Simgeyi tıklayarak veya metni seçerek bu kodu panonuza kopyalayın:", + "instruction3": "Web tarayıcınızda aşağıdaki bağlantıyı açın ve yukarıdaki kodu girin:", + "instruction4": "Kayıt işlemini tamamladığınızda aşağıdaki düğmeye basın:" + } + }, + "settings": { + "title": "Ayarlar", + "menu": { + "appearance": "Görünüm", + "language": "Dil", + "open": "Ayarları Aç" + }, + "appearance": { + "lightLabel": "Aydınlık Mod", + "darkLabel": "Karanlık Mod" + } + } +} From 4a797fcf96996b8cc2fab6db2f7827d234926aed Mon Sep 17 00:00:00 2001 From: hasanbeder Date: Mon, 28 Feb 2022 15:56:13 +0300 Subject: [PATCH 069/179] feat: Update app_widget.dart Turkish language line added. --- frontend/app_flowy/lib/startup/tasks/app_widget.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 23f4109042..7368cc3b13 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -39,6 +39,7 @@ class InitAppWidgetTask extends LaunchTask { Locale('it', 'IT'), Locale('pt', 'BR'), Locale('ru', 'RU'), + Locale('tr', 'TR'), Locale('zh', 'CN'), ], path: 'assets/translations', From 47e2571f38389c5456b1208f1ee4299f60236cb8 Mon Sep 17 00:00:00 2001 From: hasanbeder Date: Mon, 28 Feb 2022 16:00:53 +0300 Subject: [PATCH 070/179] feat: Update language.dart Turkish language line is added. --- frontend/app_flowy/packages/flowy_infra/lib/language.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/app_flowy/packages/flowy_infra/lib/language.dart b/frontend/app_flowy/packages/flowy_infra/lib/language.dart index e6726c3dbc..5567f46b8b 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/language.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/language.dart @@ -32,6 +32,8 @@ String languageFromLocale(Locale locale) { return "Português"; case "ru": return "русский"; + case "tr": + return "Türkçe"; // If not found then the language code will be displayed default: From dd589e07685a454cf04a55a32d6497b6fcdc0159 Mon Sep 17 00:00:00 2001 From: hasanbeder Date: Mon, 28 Feb 2022 16:11:45 +0300 Subject: [PATCH 071/179] feat: Delete tr-TR.json --- .../app_flowy/assets/translations/tr-TR.json | 145 ------------------ 1 file changed, 145 deletions(-) delete mode 100644 frontend/app_flowy/assets/translations/tr-TR.json diff --git a/frontend/app_flowy/assets/translations/tr-TR.json b/frontend/app_flowy/assets/translations/tr-TR.json deleted file mode 100644 index c83cace0a7..0000000000 --- a/frontend/app_flowy/assets/translations/tr-TR.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "appName": "AppFlowy", - "defaultUsername": "Ben", - "welcomeText": "@:appName'e Hoş Geldiniz!", - "githubStarText": "GitHub Yıldızı!", - "subscribeNewsletterText": "Bültene Abone Ol", - "letsGoButtonText": "Hadi başlayalım.", - "title": "Başlık", - "signUp": { - "buttonText": "Kayıt Ol", - "title": "@:appName'e kaydolun.", - "getStartedText": "başlayalım", - "emptyPasswordError": "Parola boş olamaz", - "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz", - "unmatchedPasswordError": "Parolalar eşleşmiyor", - "alreadyHaveAnAccount": "Zaten hesabınız var mı?", - "emailHint": "E-Posta", - "passwordHint": "Parola", - "repeatPasswordHint": "Tekrar parola" - }, - "signIn": { - "loginTitle": "@:appName oturum aç", - "loginButtonText": "Giriş", - "buttonText": "Oturum Aç", - "forgotPassword": "Parolanızı mı Unuttunuz?", - "emailHint": "E-Posta", - "passwordHint": "Parola", - "dontHaveAnAccount": "Hesabınız yok mu?", - "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz", - "unmatchedPasswordError": "Parolalar eşleşmiyor" - }, - "workspace": { - "create": "Çalışma alanı oluştur", - "hint": "Çalışma alanı", - "notFoundError": "Çalışma alanı bulunamadı" - }, - "shareAction": { - "buttonText": "Paylaş", - "workInProgress": "Yakında", - "markdown": "Markdown", - "copyLink": "Link'i Kopyala" - }, - "disclosureAction": { - "rename": "Yeniden adlandır", - "delete": "Sil", - "duplicate": "Çoğalt" - }, - "blankPageTitle": "Boş sayfa", - "newPageText": "Yeni sayfa", - "trash": { - "text": "Çöp", - "restoreAll": "Geri Yükle", - "deleteAll": "Sil", - "pageHeader": { - "fileName": "Dosya adı", - "lastModified": "Son Değiştirme", - "created": "Oluşturuldu" - } - }, - "deletePagePrompt": { - "text": "Bu sayfa Çöp Kutusu'nda", - "restore": "Sayfayı geri yükle", - "deletePermanent": "Kalıcı olarak sil" - }, - "dialogCreatePageNameHint": "Sayfa adı", - "questionBubble": { - "whatsNew": "Yeni ne var?", - "help": "Yardım & Destek", - "debug": { - "name": "Hata Ayıklama", - "success": "Hata ayıklama bilgileri panoya kopyalandı!", - "fail": "Hata ayıklama bilgileri panoya kopyalanamıyor" - } - }, - "menuAppHeader": { - "addPageTooltip": "Yeni bir sayfa ekleyin", - "defaultNewPageName": "Başlıksız", - "renameDialog": "Yeniden adlandır" - }, - "toolbar": { - "undo": "Geri", - "redo": "İleri", - "bold": "Kalın", - "italic": "İtalik", - "underline": "Altı Çizili", - "strike": "Üstü Çizili", - "numList": "Numaralı Liste", - "bulletList": "Madde İşaretli Liste", - "checkList": "Yapılacaklar Listesi", - "inlineCode": "Kod", - "quote": "Alıntı", - "header": "Başlık", - "highlight": "Vurgu" - }, - "tooltip": { - "lightMode": "Aydınlık Mod'a Geç", - "darkMode": "Karanlık Mod'a Geç" - }, - "contactsPage": { - "title": "İletişim", - "whatsHappening": "Bu hafta neler var?", - "addContact": "Kişi Ekle", - "editContact": "Kişiyi Düzenle" - }, - "button": { - "OK": "TAMAM", - "Cancel": "İptal", - "signIn": "Oturum Aç", - "signOut": "Oturum Kapat", - "complete": "Tamamlandı", - "save": "Kaydet" - }, - "label": { - "welcome": "Merhaba!", - "firstName": "Ad", - "middleName": "İkinci Ad", - "lastName": "Soyad", - "stepX": "Aşama {X}" - }, - "oAuth": { - "err": { - "failedTitle": "Hesabınıza bağlanılamıyor.", - "failedMsg": "Lütfen, tarayıcınızda oturum açma işlemini tamamladığınızdan emin olun." - }, - "google": { - "title": "GOOGLE OTURUM AÇMA", - "instruction1": "Google Kişilerinizi içe aktarmak için web tarayıcınızı kullanarak bu uygulamaya izin vermeniz gerekir.", - "instruction2": "Simgeyi tıklayarak veya metni seçerek bu kodu panonuza kopyalayın:", - "instruction3": "Web tarayıcınızda aşağıdaki bağlantıyı açın ve yukarıdaki kodu girin:", - "instruction4": "Kayıt işlemini tamamladığınızda aşağıdaki düğmeye basın:" - } - }, - "settings": { - "title": "Ayarlar", - "menu": { - "appearance": "Görünüm", - "language": "Dil", - "open": "Ayarları Aç" - }, - "appearance": { - "lightLabel": "Aydınlık Mod", - "darkLabel": "Karanlık Mod" - } - } -} From 32aa19dc39cff9ad685f65365b05f5f4d3f22b15 Mon Sep 17 00:00:00 2001 From: hasanbeder Date: Mon, 28 Feb 2022 16:12:59 +0300 Subject: [PATCH 072/179] feat: Add Turkish translation. Added support for the Turkish language. --- .../app_flowy/assets/translations/tr-TR.json | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 frontend/app_flowy/assets/translations/tr-TR.json diff --git a/frontend/app_flowy/assets/translations/tr-TR.json b/frontend/app_flowy/assets/translations/tr-TR.json new file mode 100644 index 0000000000..c83cace0a7 --- /dev/null +++ b/frontend/app_flowy/assets/translations/tr-TR.json @@ -0,0 +1,145 @@ +{ + "appName": "AppFlowy", + "defaultUsername": "Ben", + "welcomeText": "@:appName'e Hoş Geldiniz!", + "githubStarText": "GitHub Yıldızı!", + "subscribeNewsletterText": "Bültene Abone Ol", + "letsGoButtonText": "Hadi başlayalım.", + "title": "Başlık", + "signUp": { + "buttonText": "Kayıt Ol", + "title": "@:appName'e kaydolun.", + "getStartedText": "başlayalım", + "emptyPasswordError": "Parola boş olamaz", + "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz", + "unmatchedPasswordError": "Parolalar eşleşmiyor", + "alreadyHaveAnAccount": "Zaten hesabınız var mı?", + "emailHint": "E-Posta", + "passwordHint": "Parola", + "repeatPasswordHint": "Tekrar parola" + }, + "signIn": { + "loginTitle": "@:appName oturum aç", + "loginButtonText": "Giriş", + "buttonText": "Oturum Aç", + "forgotPassword": "Parolanızı mı Unuttunuz?", + "emailHint": "E-Posta", + "passwordHint": "Parola", + "dontHaveAnAccount": "Hesabınız yok mu?", + "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz", + "unmatchedPasswordError": "Parolalar eşleşmiyor" + }, + "workspace": { + "create": "Çalışma alanı oluştur", + "hint": "Çalışma alanı", + "notFoundError": "Çalışma alanı bulunamadı" + }, + "shareAction": { + "buttonText": "Paylaş", + "workInProgress": "Yakında", + "markdown": "Markdown", + "copyLink": "Link'i Kopyala" + }, + "disclosureAction": { + "rename": "Yeniden adlandır", + "delete": "Sil", + "duplicate": "Çoğalt" + }, + "blankPageTitle": "Boş sayfa", + "newPageText": "Yeni sayfa", + "trash": { + "text": "Çöp", + "restoreAll": "Geri Yükle", + "deleteAll": "Sil", + "pageHeader": { + "fileName": "Dosya adı", + "lastModified": "Son Değiştirme", + "created": "Oluşturuldu" + } + }, + "deletePagePrompt": { + "text": "Bu sayfa Çöp Kutusu'nda", + "restore": "Sayfayı geri yükle", + "deletePermanent": "Kalıcı olarak sil" + }, + "dialogCreatePageNameHint": "Sayfa adı", + "questionBubble": { + "whatsNew": "Yeni ne var?", + "help": "Yardım & Destek", + "debug": { + "name": "Hata Ayıklama", + "success": "Hata ayıklama bilgileri panoya kopyalandı!", + "fail": "Hata ayıklama bilgileri panoya kopyalanamıyor" + } + }, + "menuAppHeader": { + "addPageTooltip": "Yeni bir sayfa ekleyin", + "defaultNewPageName": "Başlıksız", + "renameDialog": "Yeniden adlandır" + }, + "toolbar": { + "undo": "Geri", + "redo": "İleri", + "bold": "Kalın", + "italic": "İtalik", + "underline": "Altı Çizili", + "strike": "Üstü Çizili", + "numList": "Numaralı Liste", + "bulletList": "Madde İşaretli Liste", + "checkList": "Yapılacaklar Listesi", + "inlineCode": "Kod", + "quote": "Alıntı", + "header": "Başlık", + "highlight": "Vurgu" + }, + "tooltip": { + "lightMode": "Aydınlık Mod'a Geç", + "darkMode": "Karanlık Mod'a Geç" + }, + "contactsPage": { + "title": "İletişim", + "whatsHappening": "Bu hafta neler var?", + "addContact": "Kişi Ekle", + "editContact": "Kişiyi Düzenle" + }, + "button": { + "OK": "TAMAM", + "Cancel": "İptal", + "signIn": "Oturum Aç", + "signOut": "Oturum Kapat", + "complete": "Tamamlandı", + "save": "Kaydet" + }, + "label": { + "welcome": "Merhaba!", + "firstName": "Ad", + "middleName": "İkinci Ad", + "lastName": "Soyad", + "stepX": "Aşama {X}" + }, + "oAuth": { + "err": { + "failedTitle": "Hesabınıza bağlanılamıyor.", + "failedMsg": "Lütfen, tarayıcınızda oturum açma işlemini tamamladığınızdan emin olun." + }, + "google": { + "title": "GOOGLE OTURUM AÇMA", + "instruction1": "Google Kişilerinizi içe aktarmak için web tarayıcınızı kullanarak bu uygulamaya izin vermeniz gerekir.", + "instruction2": "Simgeyi tıklayarak veya metni seçerek bu kodu panonuza kopyalayın:", + "instruction3": "Web tarayıcınızda aşağıdaki bağlantıyı açın ve yukarıdaki kodu girin:", + "instruction4": "Kayıt işlemini tamamladığınızda aşağıdaki düğmeye basın:" + } + }, + "settings": { + "title": "Ayarlar", + "menu": { + "appearance": "Görünüm", + "language": "Dil", + "open": "Ayarları Aç" + }, + "appearance": { + "lightLabel": "Aydınlık Mod", + "darkLabel": "Karanlık Mod" + } + } +} From 55b888e36443e06ca52835a607428085c7f95288 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 29 Mar 2022 11:29:21 +0800 Subject: [PATCH 073/179] chore: single selection field --- .../app_flowy/assets/translations/en.json | 5 +- .../field/type_option/option_pannel_bloc.dart | 56 ++++++ .../grid/src/widgets/content/grid_row.dart | 59 ++---- .../widgets/header/create_field_pannel.dart | 2 +- .../src/widgets/header/field_type_list.dart | 25 +-- .../widgets/header/type_option/number.dart | 2 +- .../widgets/header/type_option/selection.dart | 172 +++++++++++++++++- .../widgets/header/type_option/widget.dart | 65 +++++++ .../lib/widget/rounded_input_field.dart | 6 + 9 files changed, 333 insertions(+), 59 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 0fe9008ee6..fbd672c04f 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -163,7 +163,10 @@ "dateFormatUS": "Month/Month/Day", "timeFormat": " Time format", "timeFormatTwelveHour": "12 hour", - "timeFormatTwentyFourHour": "24 hour" + "timeFormatTwentyFourHour": "24 hour", + "addSelectOption": "Add an option", + "optionTitle": "Options", + "addOption": "Add option" } } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart new file mode 100644 index 0000000000..aacf06c98d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart @@ -0,0 +1,56 @@ +import 'dart:typed_data'; + +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'option_pannel_bloc.freezed.dart'; + +class OptionPannelBloc extends Bloc { + OptionPannelBloc({required List options}) : super(OptionPannelState.initial(options)) { + on( + (event, emit) async { + await event.map( + createOption: (_CreateOption value) async { + emit(state.copyWith(isAddingOption: false)); + }, + beginAddingOption: (_BeginAddingOption value) { + emit(state.copyWith(isAddingOption: true)); + }, + endAddingOption: (_EndAddingOption value) { + emit(state.copyWith(isAddingOption: false)); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class OptionPannelEvent with _$OptionPannelEvent { + const factory OptionPannelEvent.createOption(String optionName) = _CreateOption; + const factory OptionPannelEvent.beginAddingOption() = _BeginAddingOption; + const factory OptionPannelEvent.endAddingOption() = _EndAddingOption; +} + +@freezed +class OptionPannelState with _$OptionPannelState { + const factory OptionPannelState({ + required List options, + required bool isAddingOption, + }) = _OptionPannelState; + + factory OptionPannelState.initial(List options) => OptionPannelState( + options: options, + isAddingOption: false, + ); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index a813a51dc0..b8834cd213 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -30,47 +30,28 @@ class _GridRowWidgetState extends State { Widget build(BuildContext context) { return BlocProvider.value( value: _rowBloc, - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, + ), ), ); - // return BlocProvider.value( - // value: _rowBloc, - // child: MouseRegion( - // cursor: SystemMouseCursors.click, - // onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), - // onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - // child: BlocBuilder( - // buildWhen: (p, c) => p.rowHeight != c.rowHeight, - // builder: (context, state) { - // return SizedBox( - // height: _rowBloc.state.rowHeight, - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.stretch, - // children: const [ - // _RowLeading(), - // _RowCells(), - // _RowTrailing(), - // ], - // ), - // ); - // }, - // ), - // ), - // ); } @override diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index 8b2b74d9ae..c282f10b40 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -20,7 +20,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: _CreateFieldPannelWidget(_createFieldBloc), - constraints: BoxConstraints.loose(const Size(220, 400)), + constraints: BoxConstraints.loose(const Size(220, 500)), ), identifier: identifier(), anchorContext: context, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index dfc5c007c6..0019ffa979 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -49,17 +49,20 @@ class FieldTypeList extends StatelessWidget { ); }).toList(); - return ListView.separated( - shrinkWrap: true, - controller: ScrollController(), - itemCount: cells.length, - separatorBuilder: (context, index) { - return const VSpace(10); - }, - physics: StyledScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return cells[index]; - }, + return SizedBox( + width: 140, + child: ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + itemCount: cells.length, + separatorBuilder: (context, index) { + return const VSpace(10); + }, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index 6aeb73ac48..57a8254f2e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -111,7 +111,7 @@ class NumberFormatItem extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return SizedBox( - height: 26, + height: GridSize.typeOptionItemHeight, child: FlowyButton( text: FlowyText.medium(format.title(), fontSize: 12), hoverColor: theme.hover, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart index b5737fd219..2d5c963fc5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart @@ -1,9 +1,20 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/selection_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; + +import 'widget.dart'; class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { SingleSelectTypeOption typeOption; @@ -12,17 +23,18 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { : typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData); @override - Widget? get customWidget => const SingleSelectTypeOptionWidget(); + Widget? get customWidget => SingleSelectTypeOptionWidget(typeOption); } class SingleSelectTypeOptionWidget extends TypeOptionWidget { - const SingleSelectTypeOptionWidget({Key? key}) : super(key: key); + final SingleSelectTypeOption typeOption; + const SingleSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(), - child: Container(height: 100, color: Colors.yellow), + child: OptionPannel(options: typeOption.options), ); } } @@ -34,17 +46,165 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); @override - Widget? get customWidget => const MultiSelectTypeOptionWidget(); + Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption); } class MultiSelectTypeOptionWidget extends TypeOptionWidget { - const MultiSelectTypeOptionWidget({Key? key}) : super(key: key); + final MultiSelectTypeOption typeOption; + const MultiSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(), - child: Container(height: 100, color: Colors.blue), + child: OptionPannel(options: typeOption.options), ); } } + +class OptionPannel extends StatelessWidget { + final List options; + const OptionPannel({required this.options, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => OptionPannelBloc(options: options), + child: BlocBuilder( + builder: (context, state) { + List children = [const OptionTitle()]; + if (state.isAddingOption) { + children.add(const _AddOptionTextField()); + } + + if (state.options.isEmpty && !state.isAddingOption) { + children.add(const _AddOptionButton()); + } + + if (state.options.isNotEmpty) { + children.add(const _OptionList()); + } + + return Column(children: children); + }, + ), + ); + } +} + +class OptionTitle extends StatelessWidget { + const OptionTitle({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return BlocBuilder( + buildWhen: (previous, current) => previous.options.length != current.options.length, + builder: (context, state) { + List children = [FlowyText.medium(LocaleKeys.grid_field_optionTitle.tr(), fontSize: 12)]; + + if (state.options.isNotEmpty && state.isAddingOption == false) { + children.add(FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_addOption.tr(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + context.read().add(const OptionPannelEvent.beginAddingOption()); + }, + rightIcon: svg("grid/more", color: theme.iconColor), + )); + } + + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: Row(children: children), + ); + }, + ); + } +} + +class _OptionList extends StatelessWidget { + const _OptionList({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final optionItems = state.options.map((option) { + return _OptionItem(option: option); + }).toList(); + + return SizedBox( + width: 120, + child: ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: optionItems.length, + itemBuilder: (BuildContext context, int index) { + return optionItems[index]; + }, + ), + ); + }, + ); + } +} + +class _OptionItem extends StatelessWidget { + final SelectOption option; + const _OptionItem({required this.option, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(option.name, fontSize: 12), + hoverColor: theme.hover, + onTap: () {}, + rightIcon: svg("grid/more", color: theme.iconColor), + ), + ); + } +} + +class _AddOptionButton extends StatelessWidget { + const _AddOptionButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_addSelectOption.tr(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + context.read().add(const OptionPannelEvent.beginAddingOption()); + }, + leftIcon: svg("home/add", color: theme.iconColor), + ), + ); + } +} + +class _AddOptionTextField extends StatelessWidget { + const _AddOptionTextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return NameTextField( + name: "", + onCanceled: () { + context.read().add(const OptionPannelEvent.endAddingOption()); + }, + onDone: (optionName) { + context.read().add(OptionPannelEvent.createOption(optionName)); + }); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart new file mode 100644 index 0000000000..f357c9afea --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart @@ -0,0 +1,65 @@ +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class NameTextField extends StatefulWidget { + final void Function(String) onDone; + final void Function() onCanceled; + final String name; + + const NameTextField({ + required this.name, + required this.onDone, + required this.onCanceled, + Key? key, + }) : super(key: key); + + @override + State createState() => _NameTextFieldState(); +} + +class _NameTextFieldState extends State { + late FocusNode _focusNode; + late TextEditingController _controller; + + @override + void initState() { + _focusNode = FocusNode(); + _controller = TextEditingController(text: widget.name); + + _focusNode.addListener(notifyDidEndEditing); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return RoundedInputField( + controller: _controller, + focusNode: _focusNode, + height: 36, + style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500), + normalBorderColor: theme.shader4, + errorBorderColor: theme.red, + focusBorderColor: theme.main1, + cursorColor: theme.main1, + onChanged: (text) { + print(text); + }); + } + + @override + void dispose() { + _focusNode.removeListener(notifyDidEndEditing); + super.dispose(); + } + + void notifyDidEndEditing() { + if (_controller.text.isEmpty) { + // widget.onCanceled(); + } else { + widget.onDone(_controller.text); + } + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index 110cd29c73..b6bf1daf4b 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -20,6 +20,8 @@ class RoundedInputField extends StatefulWidget { final EdgeInsets padding; final EdgeInsets contentPadding; final double height; + final FocusNode? focusNode; + final TextEditingController? controller; const RoundedInputField({ Key? key, @@ -39,6 +41,8 @@ class RoundedInputField extends StatefulWidget { this.padding = EdgeInsets.zero, this.contentPadding = const EdgeInsets.symmetric(horizontal: 10), this.height = 48, + this.focusNode, + this.controller, }) : super(key: key); @override @@ -71,7 +75,9 @@ class _RoundedInputFieldState extends State { padding: widget.padding, height: widget.height, child: TextFormField( + controller: widget.controller, initialValue: widget.initialValue, + focusNode: widget.focusNode, onChanged: (value) { inputText = value; if (widget.onChanged != null) { From 065a72a8dad51cf58ea07e95562589042656897e Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 29 Mar 2022 22:58:38 +0800 Subject: [PATCH 074/179] chore: add option & color selection --- .../app_flowy/assets/images/grid/details.svg | 4 + .../app_flowy/assets/translations/en.json | 11 ++ .../app_flowy/lib/startup/deps_resolver.dart | 10 +- .../application/grid/field/field_service.dart | 2 - .../field/type_option/multi_select_bloc.dart | 42 +++++ .../field/type_option/option_pannel_bloc.dart | 17 +- .../field/type_option/selection_bloc.dart | 39 ----- .../field/type_option/single_select_bloc.dart | 57 ++++++ .../type_option/type_option_service.dart | 17 ++ .../workspace/application/grid/prelude.dart | 2 +- .../plugins/doc/src/document_page.dart | 1 + .../widgets/header/create_field_pannel.dart | 2 +- .../widgets/header/field_tyep_switcher.dart | 31 ++-- .../type_option/edit_option_pannel.dart | 115 ++++++++++++ .../header/type_option/multi_select.dart | 48 ++++++ .../{selection.dart => option_pannel.dart} | 137 ++++++--------- .../header/type_option/single_select.dart | 55 ++++++ .../widgets/header/type_option/widget.dart | 47 +++-- .../lib/style_widget/button.dart | 5 +- .../lib/widget/rounded_input_field.dart | 6 + .../dart_event/flowy-grid/dart_event.dart | 17 ++ .../flowy_sdk/lib/dispatch/dispatch.dart | 1 + .../flowy-error-code/code.pbenum.dart | 2 + .../flowy-error-code/code.pbjson.dart | 3 +- .../flowy-grid-data-model/grid.pb.dart | 47 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 10 ++ .../protobuf/flowy-grid/event_map.pbenum.dart | 8 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 9 +- .../rust-lib/flowy-grid/src/event_handler.rs | 10 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 10 +- .../src/protobuf/model/event_map.rs | 22 ++- .../src/protobuf/proto/event_map.proto | 7 +- shared-lib/flowy-error-code/src/code.rs | 2 + .../src/protobuf/model/code.rs | 10 +- .../src/protobuf/proto/code.proto | 1 + .../src/entities/grid.rs | 23 ++- .../flowy-grid-data-model/src/parser/mod.rs | 4 +- .../parser/{id_parser.rs => str_parser.rs} | 18 ++ .../src/protobuf/model/grid.rs | 163 +++++++++++++++++- .../src/protobuf/proto/grid.proto | 3 + 40 files changed, 828 insertions(+), 190 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/details.svg create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/{selection.dart => option_pannel.dart} (55%) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart rename shared-lib/flowy-grid-data-model/src/parser/{id_parser.rs => str_parser.rs} (54%) diff --git a/frontend/app_flowy/assets/images/grid/details.svg b/frontend/app_flowy/assets/images/grid/details.svg new file mode 100644 index 0000000000..e4c9f58f27 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/details.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index fbd672c04f..b751bb6d3e 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -167,6 +167,17 @@ "addSelectOption": "Add an option", "optionTitle": "Options", "addOption": "Add option" + }, + "selectOption": { + "purpleColor": "Purple", + "pinkColor": "Pink", + "lightPinkColor": "Light Pink", + "orangeColor": "Orange", + "yellowColor": "Yellow", + "limeColor": "Lime", + "greenColor": "Green", + "aquaColor": "Aqua", + "blueColor": "Blue" } } } diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 5d78cbdf2a..8bab77150a 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -3,6 +3,7 @@ import 'package:app_flowy/user/application/user_listener.dart'; import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/grid/row/row_listener.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; @@ -20,6 +21,7 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -215,8 +217,12 @@ void _resolveGridDeps(GetIt getIt) { (context, _) => FieldTypeSwitchBloc(context), ); - getIt.registerFactory( - () => SelectionTypeOptionBloc(), + getIt.registerFactoryParam( + (typeOption, fieldId) => SingleSelectTypeOptionBloc(typeOption, fieldId), + ); + + getIt.registerFactoryParam( + (typeOption, _) => MultiSelectTypeOptionBloc(typeOption), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 6824ce0b1b..24644f0fae 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -1,5 +1,3 @@ -import 'dart:typed_data'; - import 'package:dartz/dartz.dart'; import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart new file mode 100644 index 0000000000..75ac80c47c --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart @@ -0,0 +1,42 @@ +import 'dart:typed_data'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; + +part 'multi_select_bloc.freezed.dart'; + +class MultiSelectTypeOptionBloc extends Bloc { + MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption) : super(MultiSelectTypeOptionState.initial(typeOption)) { + on( + (event, emit) async { + await event.map( + createOption: (_CreateOption value) {}, + updateOptions: (_UpdateOptions value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class MultiSelectTypeOptionEvent with _$MultiSelectTypeOptionEvent { + const factory MultiSelectTypeOptionEvent.createOption(String optionName) = _CreateOption; + const factory MultiSelectTypeOptionEvent.updateOptions(List options) = _UpdateOptions; +} + +@freezed +class MultiSelectTypeOptionState with _$MultiSelectTypeOptionState { + const factory MultiSelectTypeOptionState({ + required MultiSelectTypeOption typeOption, + }) = _MultiSelectTypeOptionState; + + factory MultiSelectTypeOptionState.initial(MultiSelectTypeOption typeOption) => MultiSelectTypeOptionState( + typeOption: typeOption, + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart index aacf06c98d..445db413c0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart @@ -1,13 +1,8 @@ -import 'dart:typed_data'; - -import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'package:dartz/dartz.dart'; - part 'option_pannel_bloc.freezed.dart'; class OptionPannelBloc extends Bloc { @@ -16,13 +11,13 @@ class OptionPannelBloc extends Bloc { (event, emit) async { await event.map( createOption: (_CreateOption value) async { - emit(state.copyWith(isAddingOption: false)); + emit(state.copyWith(isEditingOption: false, newOptionName: Some(value.optionName))); }, beginAddingOption: (_BeginAddingOption value) { - emit(state.copyWith(isAddingOption: true)); + emit(state.copyWith(isEditingOption: true, newOptionName: none())); }, endAddingOption: (_EndAddingOption value) { - emit(state.copyWith(isAddingOption: false)); + emit(state.copyWith(isEditingOption: false, newOptionName: none())); }, ); }, @@ -46,11 +41,13 @@ class OptionPannelEvent with _$OptionPannelEvent { class OptionPannelState with _$OptionPannelState { const factory OptionPannelState({ required List options, - required bool isAddingOption, + required bool isEditingOption, + required Option newOptionName, }) = _OptionPannelState; factory OptionPannelState.initial(List options) => OptionPannelState( options: options, - isAddingOption: false, + isEditingOption: false, + newOptionName: none(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart deleted file mode 100644 index ac6d3fb6d4..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/selection_bloc.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'dart:typed_data'; - -import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'package:dartz/dartz.dart'; - -part 'selection_bloc.freezed.dart'; - -class SelectionTypeOptionBloc extends Bloc { - SelectionTypeOptionBloc() : super(SelectionTypeOptionState.initial()) { - on( - (event, emit) async { - await event.map( - initial: (_InitialField value) async {}, - ); - }, - ); - } - - @override - Future close() async { - return super.close(); - } -} - -@freezed -class SelectionTypeOptionEvent with _$SelectionTypeOptionEvent { - const factory SelectionTypeOptionEvent.initial(Uint8List? typeOptionData) = _InitialField; -} - -@freezed -class SelectionTypeOptionState with _$SelectionTypeOptionState { - const factory SelectionTypeOptionState() = _SelectionTypeOptionState; - - factory SelectionTypeOptionState.initial() => SelectionTypeOptionState(); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart new file mode 100644 index 0000000000..07a26439f3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart @@ -0,0 +1,57 @@ +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; + +import 'type_option_service.dart'; + +part 'single_select_bloc.freezed.dart'; + +class SingleSelectTypeOptionBloc extends Bloc { + final TypeOptionService service; + + SingleSelectTypeOptionBloc(SingleSelectTypeOption typeOption, String fieldId) + : service = TypeOptionService(fieldId: fieldId), + super(SingleSelectTypeOptionState.initial(typeOption)) { + on( + (event, emit) async { + await event.map( + createOption: (_CreateOption value) async { + final result = await service.createOption(value.optionName); + result.fold( + (option) { + state.typeOption.options.insert(0, option); + emit(state); + }, + (err) => Log.error(err), + ); + }, + updateOptions: (_UpdateOptions value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class SingleSelectTypeOptionEvent with _$SingleSelectTypeOptionEvent { + const factory SingleSelectTypeOptionEvent.createOption(String optionName) = _CreateOption; + const factory SingleSelectTypeOptionEvent.updateOptions(List options) = _UpdateOptions; +} + +@freezed +class SingleSelectTypeOptionState with _$SingleSelectTypeOptionState { + const factory SingleSelectTypeOptionState({ + required SingleSelectTypeOption typeOption, + }) = _SingleSelectTypeOptionState; + + factory SingleSelectTypeOptionState.initial(SingleSelectTypeOption typeOption) => SingleSelectTypeOptionState( + typeOption: typeOption, + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart new file mode 100644 index 0000000000..8ab3460b82 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart @@ -0,0 +1,17 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; + +class TypeOptionService { + String fieldId; + TypeOptionService({ + required this.fieldId, + }); + + Future> createOption(String name) { + final payload = CreateSelectOptionPayload.create()..optionName = name; + return GridEventCreateSelectOption(payload).send(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 38135f75f6..e1d3020ae0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -14,7 +14,7 @@ export 'field/switch_field_type_bloc.dart'; // Field Type Option export 'field/type_option/date_bloc.dart'; export 'field/type_option/number_bloc.dart'; -export 'field/type_option/selection_bloc.dart'; +export 'field/type_option/single_select_bloc.dart'; // Cell export 'cell_bloc/text_cell_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart index 031edb93fd..5983102047 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart @@ -61,6 +61,7 @@ class _DocumentPageState extends State { @override Future dispose() async { documentBloc.close(); + _focusNode.dispose(); super.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index c282f10b40..8b2b74d9ae 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -20,7 +20,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: _CreateFieldPannelWidget(_createFieldBloc), - constraints: BoxConstraints.loose(const Size(220, 500)), + constraints: BoxConstraints.loose(const Size(220, 400)), ), identifier: identifier(), anchorContext: context, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index 6e03b4243d..1a418cf543 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -2,7 +2,6 @@ import 'dart:typed_data'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -14,12 +13,13 @@ import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'type_option/multi_select.dart'; import 'type_option/number.dart'; +import 'type_option/single_select.dart'; typedef SelectFieldCallback = void Function(Field, Uint8List); @@ -50,7 +50,7 @@ class _FieldTypeSwitcherState extends State { final typeOptionWidget = _typeOptionWidget( context: context, - fieldType: state.field.fieldType, + field: state.field, data: state.typeOptionData, ); @@ -89,7 +89,7 @@ class _FieldTypeSwitcherState extends State { Widget? _typeOptionWidget({ required BuildContext context, - required FieldType fieldType, + required Field field, required TypeOptionData data, }) { final delegate = TypeOptionOperationDelegate( @@ -97,8 +97,9 @@ class _FieldTypeSwitcherState extends State { context.read().add(FieldTypeSwitchEvent.didUpdateTypeOptionData(data)); }, requireToShowOverlay: _showOverlay, + hideOverlay: _hideOverlay, ); - final builder = _makeTypeOptionBuild(fieldType: fieldType, data: data, delegate: delegate); + final builder = _makeTypeOptionBuild(field: field, data: data, delegate: delegate); return builder.customWidget; } @@ -120,6 +121,12 @@ class _FieldTypeSwitcherState extends State { anchorOffset: const Offset(-20, 0), ); } + + void _hideOverlay(BuildContext context) { + if (currentOverlayIdentifier != null) { + FlowyOverlay.of(context).remove(currentOverlayIdentifier!); + } + } } abstract class TypeOptionBuilder { @@ -127,23 +134,24 @@ abstract class TypeOptionBuilder { } TypeOptionBuilder _makeTypeOptionBuild({ - required FieldType fieldType, + required Field field, required TypeOptionData data, required TypeOptionOperationDelegate delegate, }) { - switch (fieldType) { + switch (field.fieldType) { case FieldType.Checkbox: return CheckboxTypeOptionBuilder(data); case FieldType.DateTime: return DateTypeOptionBuilder(data, delegate); + case FieldType.SingleSelect: + return SingleSelectTypeOptionBuilder(field.id, data, delegate); case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder(data); + return MultiSelectTypeOptionBuilder(data, delegate); case FieldType.Number: return NumberTypeOptionBuilder(data, delegate); case FieldType.RichText: return RichTextTypeOptionBuilder(data); - case FieldType.SingleSelect: - return SingleSelectTypeOptionBuilder(data); + default: throw UnimplementedError; } @@ -156,13 +164,16 @@ abstract class TypeOptionWidget extends StatelessWidget { typedef TypeOptionData = Uint8List; typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData); typedef ShowOverlayCallback = void Function(BuildContext anchorContext, String overlayIdentifier, Widget child); +typedef HideOverlayCallback = void Function(BuildContext anchorContext); class TypeOptionOperationDelegate { TypeOptionDataCallback didUpdateTypeOptionData; ShowOverlayCallback requireToShowOverlay; + HideOverlayCallback hideOverlay; TypeOptionOperationDelegate({ required this.didUpdateTypeOptionData, required this.requireToShowOverlay, + required this.hideOverlay, }); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart new file mode 100644 index 0000000000..31f9570602 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -0,0 +1,115 @@ +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; + +class SelectOptionColorList extends StatelessWidget { + const SelectOptionColorList({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); + } +} + +class _SelectOptionColorItem extends StatelessWidget { + final SelectOptionColor option; + final bool isSelected; + const _SelectOptionColorItem({required this.option, required this.isSelected, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + Widget? checkmark; + if (isSelected) { + checkmark = svg("grid/details", color: theme.iconColor); + } + + final colorIcon = SizedBox.square( + dimension: 16, + child: Container( + decoration: BoxDecoration( + color: option.color(context), + shape: BoxShape.circle, + ), + ), + ); + + return FlowyButton( + text: FlowyText.medium( + option.name(), + fontSize: 12, + ), + hoverColor: theme.hover, + leftIcon: colorIcon, + rightIcon: checkmark, + onTap: () {}, + ); + } +} + +enum SelectOptionColor { + purple, + pink, + lightPink, + orange, + yellow, + lime, + green, + aqua, + blue, +} + +extension SelectOptionColorExtension on SelectOptionColor { + Color color(BuildContext context) { + final theme = context.watch(); + switch (this) { + case SelectOptionColor.purple: + return theme.tint1; + case SelectOptionColor.pink: + return theme.tint2; + case SelectOptionColor.lightPink: + return theme.tint3; + case SelectOptionColor.orange: + return theme.tint4; + case SelectOptionColor.yellow: + return theme.tint5; + case SelectOptionColor.lime: + return theme.tint6; + case SelectOptionColor.green: + return theme.tint7; + case SelectOptionColor.aqua: + return theme.tint8; + case SelectOptionColor.blue: + return theme.tint9; + } + } + + String name() { + switch (this) { + case SelectOptionColor.purple: + return LocaleKeys.grid_selectOption_purpleColor.tr(); + case SelectOptionColor.pink: + return LocaleKeys.grid_selectOption_pinkColor.tr(); + case SelectOptionColor.lightPink: + return LocaleKeys.grid_selectOption_lightPinkColor.tr(); + case SelectOptionColor.orange: + return LocaleKeys.grid_selectOption_orangeColor.tr(); + case SelectOptionColor.yellow: + return LocaleKeys.grid_selectOption_yellowColor.tr(); + case SelectOptionColor.lime: + return LocaleKeys.grid_selectOption_limeColor.tr(); + case SelectOptionColor.green: + return LocaleKeys.grid_selectOption_greenColor.tr(); + case SelectOptionColor.aqua: + return LocaleKeys.grid_selectOption_aquaColor.tr(); + case SelectOptionColor.blue: + return LocaleKeys.grid_selectOption_blueColor.tr(); + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart new file mode 100644 index 0000000000..4a3694b5fc --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -0,0 +1,48 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'option_pannel.dart'; + +class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { + MultiSelectTypeOption typeOption; + TypeOptionOperationDelegate delegate; + + MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate) + : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); + + @override + Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption, delegate); +} + +class MultiSelectTypeOptionWidget extends TypeOptionWidget { + final MultiSelectTypeOption typeOption; + final TypeOptionOperationDelegate delegate; + const MultiSelectTypeOptionWidget(this.typeOption, this.delegate, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: typeOption), + child: BlocBuilder( + builder: (context, state) { + return OptionPannel( + options: state.typeOption.options, + beginEdit: () { + delegate.hideOverlay(context); + }, + createOptionCallback: (name) { + context.read().add(MultiSelectTypeOptionEvent.createOption(name)); + }, + updateOptionsCallback: (options) { + context.read().add(MultiSelectTypeOptionEvent.updateOptions(options)); + }, + ); + }, + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart similarity index 55% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart index 2d5c963fc5..736d03d96d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart @@ -1,8 +1,5 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/field/type_option/selection_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; @@ -16,73 +13,48 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'widget.dart'; -class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { - SingleSelectTypeOption typeOption; - - SingleSelectTypeOptionBuilder(TypeOptionData typeOptionData) - : typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData); - - @override - Widget? get customWidget => SingleSelectTypeOptionWidget(typeOption); -} - -class SingleSelectTypeOptionWidget extends TypeOptionWidget { - final SingleSelectTypeOption typeOption; - const SingleSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(), - child: OptionPannel(options: typeOption.options), - ); - } -} - -class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { - MultiSelectTypeOption typeOption; - - MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData) - : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); - - @override - Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption); -} - -class MultiSelectTypeOptionWidget extends TypeOptionWidget { - final MultiSelectTypeOption typeOption; - const MultiSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(), - child: OptionPannel(options: typeOption.options), - ); - } -} - class OptionPannel extends StatelessWidget { final List options; - const OptionPannel({required this.options, Key? key}) : super(key: key); + final VoidCallback beginEdit; + final Function(String optionName) createOptionCallback; + final Function(List) updateOptionsCallback; + const OptionPannel({ + required this.options, + required this.beginEdit, + required this.createOptionCallback, + required this.updateOptionsCallback, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => OptionPannelBloc(options: options), - child: BlocBuilder( + child: BlocConsumer( + listener: (context, state) { + if (state.isEditingOption) { + beginEdit(); + } + state.newOptionName.fold( + () => null, + (optionName) => createOptionCallback(optionName), + ); + }, builder: (context, state) { - List children = [const OptionTitle()]; - if (state.isAddingOption) { + List children = [ + const TypeOptionSeparator(), + const OptionTitle(), + ]; + if (state.isEditingOption) { children.add(const _AddOptionTextField()); } - if (state.options.isEmpty && !state.isAddingOption) { + if (state.options.isEmpty && !state.isEditingOption) { children.add(const _AddOptionButton()); } if (state.options.isNotEmpty) { - children.add(const _OptionList()); + children.add(_OptionList(key: ObjectKey(state.options))); } return Column(children: children); @@ -100,19 +72,27 @@ class OptionTitle extends StatelessWidget { final theme = context.watch(); return BlocBuilder( - buildWhen: (previous, current) => previous.options.length != current.options.length, builder: (context, state) { List children = [FlowyText.medium(LocaleKeys.grid_field_optionTitle.tr(), fontSize: 12)]; - - if (state.options.isNotEmpty && state.isAddingOption == false) { - children.add(FlowyButton( - text: FlowyText.medium(LocaleKeys.grid_field_addOption.tr(), fontSize: 12), - hoverColor: theme.hover, - onTap: () { - context.read().add(const OptionPannelEvent.beginAddingOption()); - }, - rightIcon: svg("grid/more", color: theme.iconColor), - )); + if (state.options.isNotEmpty) { + children.add(const Spacer()); + children.add( + SizedBox( + width: 100, + height: 26, + child: FlowyButton( + text: FlowyText.medium( + LocaleKeys.grid_field_addOption.tr(), + fontSize: 12, + textAlign: TextAlign.center, + ), + hoverColor: theme.hover, + onTap: () { + context.read().add(const OptionPannelEvent.beginAddingOption()); + }, + ), + ), + ); } return SizedBox( @@ -135,19 +115,16 @@ class _OptionList extends StatelessWidget { return _OptionItem(option: option); }).toList(); - return SizedBox( - width: 120, - child: ListView.separated( - shrinkWrap: true, - controller: ScrollController(), - separatorBuilder: (context, index) { - return VSpace(GridSize.typeOptionSeparatorHeight); - }, - itemCount: optionItems.length, - itemBuilder: (BuildContext context, int index) { - return optionItems[index]; - }, - ), + return ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: optionItems.length, + itemBuilder: (BuildContext context, int index) { + return optionItems[index]; + }, ); }, ); @@ -167,7 +144,7 @@ class _OptionItem extends StatelessWidget { text: FlowyText.medium(option.name, fontSize: 12), hoverColor: theme.hover, onTap: () {}, - rightIcon: svg("grid/more", color: theme.iconColor), + rightIcon: svg("grid/details", color: theme.iconColor), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart new file mode 100644 index 0000000000..6690729ff0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -0,0 +1,55 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'option_pannel.dart'; + +class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { + final SingleSelectTypeOptionWidget _widget; + + SingleSelectTypeOptionBuilder( + String fieldId, + TypeOptionData typeOptionData, + TypeOptionOperationDelegate delegate, + ) : _widget = SingleSelectTypeOptionWidget( + fieldId, + SingleSelectTypeOption.fromBuffer(typeOptionData), + delegate, + ); + + @override + Widget? get customWidget => _widget; +} + +class SingleSelectTypeOptionWidget extends TypeOptionWidget { + final String fieldId; + final SingleSelectTypeOption typeOption; + final TypeOptionOperationDelegate delegate; + const SingleSelectTypeOptionWidget(this.fieldId, this.typeOption, this.delegate, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: typeOption, param2: fieldId), + child: BlocConsumer( + listener: (context, state) => delegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), + builder: (context, state) { + return OptionPannel( + options: state.typeOption.options, + beginEdit: () { + delegate.hideOverlay(context); + }, + createOptionCallback: (name) { + context.read().add(SingleSelectTypeOptionEvent.createOption(name)); + }, + updateOptionsCallback: (options) { + context.read().add(SingleSelectTypeOptionEvent.updateOptions(options)); + }, + ); + }, + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart index f357c9afea..6f4e86a4e1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart @@ -21,6 +21,7 @@ class NameTextField extends StatefulWidget { class _NameTextFieldState extends State { late FocusNode _focusNode; + var isEdited = false; late TextEditingController _controller; @override @@ -35,31 +36,53 @@ class _NameTextFieldState extends State { @override Widget build(BuildContext context) { final theme = context.watch(); + return RoundedInputField( - controller: _controller, - focusNode: _focusNode, - height: 36, - style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500), - normalBorderColor: theme.shader4, - errorBorderColor: theme.red, - focusBorderColor: theme.main1, - cursorColor: theme.main1, - onChanged: (text) { - print(text); - }); + controller: _controller, + focusNode: _focusNode, + autoFocus: true, + height: 36, + style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500), + normalBorderColor: theme.shader4, + focusBorderColor: theme.main1, + cursorColor: theme.main1, + onEditingComplete: () { + widget.onDone(_controller.text); + }, + ); } @override void dispose() { _focusNode.removeListener(notifyDidEndEditing); + _focusNode.dispose(); super.dispose(); } void notifyDidEndEditing() { if (_controller.text.isEmpty) { - // widget.onCanceled(); + if (isEdited) { + widget.onCanceled(); + } + isEdited = true; } else { widget.onDone(_controller.text); } } } + +class TypeOptionSeparator extends StatelessWidget { + const TypeOptionSeparator({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: Container( + color: theme.shader4, + height: 0.25, + ), + ); + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 0bcd05f56e..13d02a0ea8 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -15,7 +15,7 @@ class FlowyButton extends StatelessWidget { Key? key, required this.text, this.onTap, - this.padding = const EdgeInsets.symmetric(horizontal: 3, vertical: 2), + this.padding = const EdgeInsets.symmetric(horizontal: 6, vertical: 2), this.leftIcon, this.rightIcon, this.hoverColor = Colors.transparent, @@ -44,12 +44,13 @@ class FlowyButton extends StatelessWidget { if (rightIcon != null) { children.add(SizedBox.fromSize(size: const Size.square(16), child: rightIcon!)); - children.add(const HSpace(6)); } return Padding( padding: padding, child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: children, ), ); diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index b6bf1daf4b..0af5e4ec89 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -15,6 +15,7 @@ class RoundedInputField extends StatefulWidget { final String errorText; final TextStyle style; final ValueChanged? onChanged; + final VoidCallback? onEditingComplete; final String? initialValue; final EdgeInsets margin; final EdgeInsets padding; @@ -22,6 +23,7 @@ class RoundedInputField extends StatefulWidget { final double height; final FocusNode? focusNode; final TextEditingController? controller; + final bool autoFocus; const RoundedInputField({ Key? key, @@ -32,6 +34,7 @@ class RoundedInputField extends StatefulWidget { this.obscureIcon, this.obscureHideIcon, this.onChanged, + this.onEditingComplete, this.normalBorderColor = Colors.transparent, this.errorBorderColor = Colors.transparent, this.focusBorderColor, @@ -43,6 +46,7 @@ class RoundedInputField extends StatefulWidget { this.height = 48, this.focusNode, this.controller, + this.autoFocus = false, }) : super(key: key); @override @@ -78,6 +82,7 @@ class _RoundedInputFieldState extends State { controller: widget.controller, initialValue: widget.initialValue, focusNode: widget.focusNode, + autofocus: widget.autoFocus, onChanged: (value) { inputText = value; if (widget.onChanged != null) { @@ -85,6 +90,7 @@ class _RoundedInputFieldState extends State { } setState(() {}); }, + onEditingComplete: widget.onEditingComplete, cursorColor: widget.cursorColor, obscureText: obscuteText, style: widget.style, 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 7f25329284..04098b288e 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 @@ -137,6 +137,23 @@ class GridEventCreateEditFieldContext { } } +class GridEventCreateSelectOption { + CreateSelectOptionPayload request; + GridEventCreateSelectOption(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.CreateSelectOption.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(SelectOption.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateRow { CreateRowPayload request; GridEventCreateRow(this.request); 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 b068956465..e2be9f11a2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -4,6 +4,7 @@ import 'package:flowy_sdk/log.dart'; // ignore: unnecessary_import import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; 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'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index 307b9f86f2..9c4e31eeea 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -47,6 +47,7 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode RowIdIsEmpty = ErrorCode._(430, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); static const ErrorCode FieldIdIsEmpty = ErrorCode._(440, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldIdIsEmpty'); static const ErrorCode FieldDoesNotExist = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldDoesNotExist'); + static const ErrorCode SelectOptionNameIsEmpty = ErrorCode._(442, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SelectOptionNameIsEmpty'); static const ErrorCode TypeOptionDataIsEmpty = ErrorCode._(450, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionDataIsEmpty'); static const ErrorCode InvalidData = ErrorCode._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); @@ -88,6 +89,7 @@ class ErrorCode extends $pb.ProtobufEnum { RowIdIsEmpty, FieldIdIsEmpty, FieldDoesNotExist, + SelectOptionNameIsEmpty, TypeOptionDataIsEmpty, InvalidData, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 9345118baa..b3efa2c0ad 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -49,10 +49,11 @@ const ErrorCode$json = const { const {'1': 'RowIdIsEmpty', '2': 430}, const {'1': 'FieldIdIsEmpty', '2': 440}, const {'1': 'FieldDoesNotExist', '2': 441}, + const {'1': 'SelectOptionNameIsEmpty', '2': 442}, const {'1': 'TypeOptionDataIsEmpty', '2': 450}, const {'1': 'InvalidData', '2': 500}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFGaWVsZERvZXNOb3RFeGlzdBC5AxIaChVUeXBlT3B0aW9uRGF0YUlzRW1wdHkQwgMSEAoLSW52YWxpZERhdGEQ9AM='); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFGaWVsZERvZXNOb3RFeGlzdBC5AxIcChdTZWxlY3RPcHRpb25OYW1lSXNFbXB0eRC6AxIaChVUeXBlT3B0aW9uRGF0YUlzRW1wdHkQwgMSEAoLSW52YWxpZERhdGEQ9AM='); 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 bd9afe2243..3dafd193b3 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 @@ -1536,3 +1536,50 @@ class QueryRowPayload extends $pb.GeneratedMessage { void clearRowId() => clearField(3); } +class CreateSelectOptionPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') + ..hasRequiredFields = false + ; + + CreateSelectOptionPayload._() : super(); + factory CreateSelectOptionPayload({ + $core.String? optionName, + }) { + final _result = create(); + if (optionName != null) { + _result.optionName = optionName; + } + return _result; + } + factory CreateSelectOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateSelectOptionPayload.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') + CreateSelectOptionPayload clone() => CreateSelectOptionPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateSelectOptionPayload copyWith(void Function(CreateSelectOptionPayload) updates) => super.copyWith((message) => updates(message as CreateSelectOptionPayload)) as CreateSelectOptionPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateSelectOptionPayload create() => CreateSelectOptionPayload._(); + CreateSelectOptionPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateSelectOptionPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateSelectOptionPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get optionName => $_getSZ(0); + @$pb.TagNumber(1) + set optionName($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasOptionName() => $_has(0); + @$pb.TagNumber(1) + void clearOptionName() => clearField(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 0b900d46f9..3b7c58924e 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 @@ -302,3 +302,13 @@ const QueryRowPayload$json = const { /// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); +@$core.Deprecated('Use createSelectOptionPayloadDescriptor instead') +const CreateSelectOptionPayload$json = const { + '1': 'CreateSelectOptionPayload', + '2': const [ + const {'1': 'option_name', '3': 1, '4': 1, '5': 9, '10': 'optionName'}, + ], +}; + +/// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1l'); 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 46291923e0..25319128d8 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 @@ -18,9 +18,10 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField'); static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); static const GridEvent CreateEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); - static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); - static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); - static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent CreateSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateSelectOption'); + static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); + static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, @@ -31,6 +32,7 @@ class GridEvent extends $pb.ProtobufEnum { DeleteField, DuplicateField, CreateEditFieldContext, + CreateSelectOption, CreateRow, GetRow, UpdateCell, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 278e0b14c3..747a591a02 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 @@ -20,11 +20,12 @@ const GridEvent$json = const { const {'1': 'DeleteField', '2': 13}, const {'1': 'DuplicateField', '2': 15}, const {'1': 'CreateEditFieldContext', '2': 16}, - const {'1': 'CreateRow', '2': 21}, - const {'1': 'GetRow', '2': 22}, - const {'1': 'UpdateCell', '2': 30}, + const {'1': 'CreateSelectOption', '2': 30}, + const {'1': 'CreateRow', '2': 50}, + const {'1': 'GetRow', '2': 51}, + const {'1': 'UpdateCell', '2': 70}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIaChZDcmVhdGVFZGl0RmllbGRDb250ZXh0EBASDQoJQ3JlYXRlUm93EBUSCgoGR2V0Um93EBYSDgoKVXBkYXRlQ2VsbBAe'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIaChZDcmVhdGVFZGl0RmllbGRDb250ZXh0EBASFgoSQ3JlYXRlU2VsZWN0T3B0aW9uEB4SDQoJQ3JlYXRlUm93EDISCgoGR2V0Um93EDMSDgoKVXBkYXRlQ2VsbBBG'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 97b91e5557..d29c2aec48 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,5 +1,5 @@ use crate::manager::GridManager; -use crate::services::field::type_option_data_from_str; +use crate::services::field::{type_option_data_from_str, SelectOption}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; @@ -88,6 +88,14 @@ pub(crate) async fn duplicate_field_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip(data), err)] +pub(crate) async fn create_select_option_handler( + data: Data, +) -> DataResult { + let params: CreateSelectOptionParams = data.into_inner().try_into()?; + data_result(SelectOption::new(¶ms.option_name)) +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_edit_field_context_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index efe5ddc094..966423c7c7 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -16,6 +16,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::DeleteField, delete_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) .event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler) + .event(GridEvent::CreateSelectOption, create_select_option_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); @@ -50,12 +51,15 @@ pub enum GridEvent { #[event(input = "CreateEditFieldContextParams", output = "EditFieldContext")] CreateEditFieldContext = 16, + #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] + CreateSelectOption = 30, + #[event(input = "CreateRowPayload", output = "Row")] - CreateRow = 21, + CreateRow = 50, #[event(input = "QueryRowPayload", output = "Row")] - GetRow = 22, + GetRow = 51, #[event(input = "CellMetaChangeset")] - UpdateCell = 30, + UpdateCell = 70, } 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 13ee0705cc..2eab7357c5 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 @@ -33,9 +33,10 @@ pub enum GridEvent { DeleteField = 13, DuplicateField = 15, CreateEditFieldContext = 16, - CreateRow = 21, - GetRow = 22, - UpdateCell = 30, + CreateSelectOption = 30, + CreateRow = 50, + GetRow = 51, + UpdateCell = 70, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -53,9 +54,10 @@ impl ::protobuf::ProtobufEnum for GridEvent { 13 => ::std::option::Option::Some(GridEvent::DeleteField), 15 => ::std::option::Option::Some(GridEvent::DuplicateField), 16 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), - 21 => ::std::option::Option::Some(GridEvent::CreateRow), - 22 => ::std::option::Option::Some(GridEvent::GetRow), - 30 => ::std::option::Option::Some(GridEvent::UpdateCell), + 30 => ::std::option::Option::Some(GridEvent::CreateSelectOption), + 50 => ::std::option::Option::Some(GridEvent::CreateRow), + 51 => ::std::option::Option::Some(GridEvent::GetRow), + 70 => ::std::option::Option::Some(GridEvent::UpdateCell), _ => ::std::option::Option::None } } @@ -70,6 +72,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::DeleteField, GridEvent::DuplicateField, GridEvent::CreateEditFieldContext, + GridEvent::CreateSelectOption, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, @@ -101,12 +104,13 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xcc\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xe4\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x12\n\x0eDuplicateField\x10\x0f\x12\x1a\n\x16CreateE\ - ditFieldContext\x10\x10\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\x10\ - \x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\ + ditFieldContext\x10\x10\x12\x16\n\x12CreateSelectOption\x10\x1e\x12\r\n\ + \tCreateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10Fb\x06p\ + roto3\ "; 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 327a1e3aee..ebc7ae6782 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 @@ -9,7 +9,8 @@ enum GridEvent { DeleteField = 13; DuplicateField = 15; CreateEditFieldContext = 16; - CreateRow = 21; - GetRow = 22; - UpdateCell = 30; + CreateSelectOption = 30; + CreateRow = 50; + GetRow = 51; + UpdateCell = 70; } diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index 7c813bd1e0..3b0cf331ee 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -99,6 +99,8 @@ pub enum ErrorCode { FieldIdIsEmpty = 440, #[display(fmt = "Field doesn't exist")] FieldDoesNotExist = 441, + #[display(fmt = "The name of the option should not be empty")] + SelectOptionNameIsEmpty = 442, #[display(fmt = "Field's type option data should not be empty")] TypeOptionDataIsEmpty = 450, diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index 8e6e1b9621..6e6db9139b 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -62,6 +62,7 @@ pub enum ErrorCode { RowIdIsEmpty = 430, FieldIdIsEmpty = 440, FieldDoesNotExist = 441, + SelectOptionNameIsEmpty = 442, TypeOptionDataIsEmpty = 450, InvalidData = 500, } @@ -110,6 +111,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 430 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), 440 => ::std::option::Option::Some(ErrorCode::FieldIdIsEmpty), 441 => ::std::option::Option::Some(ErrorCode::FieldDoesNotExist), + 442 => ::std::option::Option::Some(ErrorCode::SelectOptionNameIsEmpty), 450 => ::std::option::Option::Some(ErrorCode::TypeOptionDataIsEmpty), 500 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None @@ -155,6 +157,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::RowIdIsEmpty, ErrorCode::FieldIdIsEmpty, ErrorCode::FieldDoesNotExist, + ErrorCode::SelectOptionNameIsEmpty, ErrorCode::TypeOptionDataIsEmpty, ErrorCode::InvalidData, ]; @@ -185,7 +188,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\x80\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\x9e\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\ \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\ @@ -205,8 +208,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x12\n\rG\ ridIdIsEmpty\x10\x9a\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\xa4\x03\x12\x11\ \n\x0cRowIdIsEmpty\x10\xae\x03\x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\ - \x12\x16\n\x11FieldDoesNotExist\x10\xb9\x03\x12\x1a\n\x15TypeOptionDataI\ - sEmpty\x10\xc2\x03\x12\x10\n\x0bInvalidData\x10\xf4\x03b\x06proto3\ + \x12\x16\n\x11FieldDoesNotExist\x10\xb9\x03\x12\x1c\n\x17SelectOptionNam\ + eIsEmpty\x10\xba\x03\x12\x1a\n\x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\ + \x10\n\x0bInvalidData\x10\xf4\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index e01c42aa8b..d435d558dc 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -38,6 +38,7 @@ enum ErrorCode { RowIdIsEmpty = 430; FieldIdIsEmpty = 440; FieldDoesNotExist = 441; + SelectOptionNameIsEmpty = 442; TypeOptionDataIsEmpty = 450; InvalidData = 500; } 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 dfd5dc397f..a85b8d382a 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,5 +1,5 @@ use crate::entities::{FieldMeta, FieldType, RowMeta}; -use crate::parser::NotEmptyUuid; +use crate::parser::{NotEmptyStr, NotEmptyUuid}; use flowy_derive::ProtoBuf; use flowy_error_code::ErrorCode; use std::collections::HashMap; @@ -494,3 +494,24 @@ impl TryInto for QueryRowPayload { }) } } + +#[derive(ProtoBuf, Default)] +pub struct CreateSelectOptionPayload { + #[pb(index = 1)] + pub option_name: String, +} + +pub struct CreateSelectOptionParams { + pub option_name: String, +} + +impl TryInto for CreateSelectOptionPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; + Ok(CreateSelectOptionParams { + option_name: option_name.0, + }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/mod.rs b/shared-lib/flowy-grid-data-model/src/parser/mod.rs index 7cb72eb859..3c43c76f39 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/mod.rs @@ -1,3 +1,3 @@ -mod id_parser; +mod str_parser; -pub use id_parser::*; +pub use str_parser::*; diff --git a/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs b/shared-lib/flowy-grid-data-model/src/parser/str_parser.rs similarity index 54% rename from shared-lib/flowy-grid-data-model/src/parser/id_parser.rs rename to shared-lib/flowy-grid-data-model/src/parser/str_parser.rs index 5003ab2ce4..3e5e3c622b 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/id_parser.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/str_parser.rs @@ -19,3 +19,21 @@ impl AsRef for NotEmptyUuid { &self.0 } } + +#[derive(Debug)] +pub struct NotEmptyStr(pub String); + +impl NotEmptyStr { + pub fn parse(s: String) -> Result { + if s.trim().is_empty() { + return Err("Input string is empty".to_owned()); + } + Ok(Self(s)) + } +} + +impl AsRef for NotEmptyStr { + fn as_ref(&self) -> &str { + &self.0 + } +} 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 c18043184f..d55c5dac10 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 @@ -5258,6 +5258,165 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct CreateSelectOptionPayload { + // message fields + pub option_name: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateSelectOptionPayload { + fn default() -> &'a CreateSelectOptionPayload { + ::default_instance() + } +} + +impl CreateSelectOptionPayload { + pub fn new() -> CreateSelectOptionPayload { + ::std::default::Default::default() + } + + // string option_name = 1; + + + pub fn get_option_name(&self) -> &str { + &self.option_name + } + pub fn clear_option_name(&mut self) { + self.option_name.clear(); + } + + // Param is passed by value, moved + pub fn set_option_name(&mut self, v: ::std::string::String) { + self.option_name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_option_name(&mut self) -> &mut ::std::string::String { + &mut self.option_name + } + + // Take field + pub fn take_option_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.option_name, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for CreateSelectOptionPayload { + 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.option_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.option_name.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.option_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.option_name.is_empty() { + os.write_string(1, &self.option_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() -> CreateSelectOptionPayload { + CreateSelectOptionPayload::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>( + "option_name", + |m: &CreateSelectOptionPayload| { &m.option_name }, + |m: &mut CreateSelectOptionPayload| { &mut m.option_name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateSelectOptionPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateSelectOptionPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateSelectOptionPayload::new) + } +} + +impl ::protobuf::Clear for CreateSelectOptionPayload { + fn clear(&mut self) { + self.option_name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateSelectOptionPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateSelectOptionPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\ngrid.proto\x1a\nmeta.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ @@ -5311,7 +5470,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ \x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\ + kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"<\n\x19CreateSelec\ + tOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionNameb\ + \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 3a74e23026..5c07b98d30 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 @@ -103,3 +103,6 @@ message QueryRowPayload { string block_id = 2; string row_id = 3; } +message CreateSelectOptionPayload { + string option_name = 1; +} From 547b8ec29c97dd0295337530b47e1619a8eb00bd Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 30 Mar 2022 22:51:52 +0800 Subject: [PATCH 075/179] fix: fix bugs --- .../app_flowy/assets/translations/en.json | 4 +- .../field/type_option/option_pannel_bloc.dart | 12 ++ .../field/type_option/single_select_bloc.dart | 52 +++++- .../widgets/header/field_tyep_switcher.dart | 62 ++++--- .../src/widgets/header/field_type_list.dart | 16 -- .../src/widgets/header/type_option/date.dart | 35 ++-- .../type_option/edit_option_pannel.dart | 155 ++++++++++++++++-- .../header/type_option/multi_select.dart | 14 +- .../widgets/header/type_option/number.dart | 28 ++-- .../header/type_option/option_pannel.dart | 67 ++++++-- .../header/type_option/single_select.dart | 36 ++-- 11 files changed, 373 insertions(+), 108 deletions(-) diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index b751bb6d3e..4bb37ea078 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -177,7 +177,9 @@ "limeColor": "Lime", "greenColor": "Green", "aquaColor": "Aqua", - "blueColor": "Blue" + "blueColor": "Blue", + "deleteTag": "Delete tag", + "colorPannelTitle": "Colors" } } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart index 445db413c0..715cde72d7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart @@ -19,6 +19,12 @@ class OptionPannelBloc extends Bloc { endAddingOption: (_EndAddingOption value) { emit(state.copyWith(isEditingOption: false, newOptionName: none())); }, + updateOption: (_UpdateOption value) { + emit(state.copyWith(updateOption: Some(value.option))); + }, + deleteOption: (_DeleteOption value) { + emit(state.copyWith(deleteOption: Some(value.option))); + }, ); }, ); @@ -35,6 +41,8 @@ class OptionPannelEvent with _$OptionPannelEvent { const factory OptionPannelEvent.createOption(String optionName) = _CreateOption; const factory OptionPannelEvent.beginAddingOption() = _BeginAddingOption; const factory OptionPannelEvent.endAddingOption() = _EndAddingOption; + const factory OptionPannelEvent.updateOption(SelectOption option) = _UpdateOption; + const factory OptionPannelEvent.deleteOption(SelectOption option) = _DeleteOption; } @freezed @@ -43,11 +51,15 @@ class OptionPannelState with _$OptionPannelState { required List options, required bool isEditingOption, required Option newOptionName, + required Option updateOption, + required Option deleteOption, }) = _OptionPannelState; factory OptionPannelState.initial(List options) => OptionPannelState( options: options, isEditingOption: false, newOptionName: none(), + updateOption: none(), + deleteOption: none(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart index 07a26439f3..03053b2dbb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart @@ -3,7 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; - +import 'package:protobuf/protobuf.dart'; import 'type_option_service.dart'; part 'single_select_bloc.freezed.dart'; @@ -11,9 +11,13 @@ part 'single_select_bloc.freezed.dart'; class SingleSelectTypeOptionBloc extends Bloc { final TypeOptionService service; - SingleSelectTypeOptionBloc(SingleSelectTypeOption typeOption, String fieldId) - : service = TypeOptionService(fieldId: fieldId), - super(SingleSelectTypeOptionState.initial(typeOption)) { + SingleSelectTypeOptionBloc( + SingleSelectTypeOption typeOption, + String fieldId, + ) : service = TypeOptionService(fieldId: fieldId), + super( + SingleSelectTypeOptionState.initial(typeOption), + ) { on( (event, emit) async { await event.map( @@ -21,13 +25,17 @@ class SingleSelectTypeOptionBloc extends Bloc Log.error(err), ); }, - updateOptions: (_UpdateOptions value) async {}, + updateOption: (_UpdateOption value) async { + emit(state.copyWith(typeOption: _updateOption(value.option))); + }, + deleteOption: (_DeleteOption value) { + emit(state.copyWith(typeOption: _deleteOption(value.option))); + }, ); }, ); @@ -37,12 +45,40 @@ class SingleSelectTypeOptionBloc extends Bloc close() async { return super.close(); } + + SingleSelectTypeOption _insertOption(SelectOption option) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + typeOption.options.insert(0, option); + }); + } + + SingleSelectTypeOption _updateOption(SelectOption option) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + final index = typeOption.options.indexWhere((element) => element.id == option.id); + if (index != -1) { + typeOption.options[index] = option; + } + }); + } + + SingleSelectTypeOption _deleteOption(SelectOption option) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + final index = typeOption.options.indexWhere((element) => element.id == option.id); + if (index != -1) { + typeOption.options.removeAt(index); + } + }); + } } @freezed class SingleSelectTypeOptionEvent with _$SingleSelectTypeOptionEvent { const factory SingleSelectTypeOptionEvent.createOption(String optionName) = _CreateOption; - const factory SingleSelectTypeOptionEvent.updateOptions(List options) = _UpdateOptions; + const factory SingleSelectTypeOptionEvent.updateOption(SelectOption option) = _UpdateOption; + const factory SingleSelectTypeOptionEvent.deleteOption(SelectOption option) = _DeleteOption; } @freezed diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index 1a418cf543..ce34097118 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -79,7 +79,7 @@ class _FieldTypeSwitcherState extends State { final list = FieldTypeList(onSelectField: (fieldType) { context.read().add(FieldTypeSwitchEvent.toFieldType(fieldType)); }); - _showOverlay(context, FieldTypeList.identifier(), list); + _showOverlay(context, list); }, leftIcon: svg(field.fieldType.iconName(), color: theme.iconColor), rightIcon: svg("grid/more", color: theme.iconColor), @@ -92,18 +92,27 @@ class _FieldTypeSwitcherState extends State { required Field field, required TypeOptionData data, }) { - final delegate = TypeOptionOperationDelegate( - didUpdateTypeOptionData: (data) { - context.read().add(FieldTypeSwitchEvent.didUpdateTypeOptionData(data)); - }, - requireToShowOverlay: _showOverlay, + final overlayDelegate = TypeOptionOverlayDelegate( + showOverlay: _showOverlay, hideOverlay: _hideOverlay, ); - final builder = _makeTypeOptionBuild(field: field, data: data, delegate: delegate); + + final dataDelegate = TypeOptionDataDelegate(didUpdateTypeOptionData: (data) { + context.read().add(FieldTypeSwitchEvent.didUpdateTypeOptionData(data)); + }); + + final builder = _makeTypeOptionBuild( + field: field, + data: data, + overlayDelegate: overlayDelegate, + dataDelegate: dataDelegate, + ); + return builder.customWidget; } - void _showOverlay(BuildContext context, String identifier, Widget child) { + void _showOverlay(BuildContext context, Widget child, {VoidCallback? onRemoved}) { + final identifier = child.toString(); if (currentOverlayIdentifier != null) { FlowyOverlay.of(context).remove(currentOverlayIdentifier!); } @@ -112,7 +121,7 @@ class _FieldTypeSwitcherState extends State { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: child, - constraints: BoxConstraints.loose(const Size(240, 400)), + constraints: BoxConstraints.loose(const Size(340, 400)), ), identifier: identifier, anchorContext: context, @@ -136,19 +145,20 @@ abstract class TypeOptionBuilder { TypeOptionBuilder _makeTypeOptionBuild({ required Field field, required TypeOptionData data, - required TypeOptionOperationDelegate delegate, + required TypeOptionOverlayDelegate overlayDelegate, + required TypeOptionDataDelegate dataDelegate, }) { switch (field.fieldType) { case FieldType.Checkbox: return CheckboxTypeOptionBuilder(data); case FieldType.DateTime: - return DateTypeOptionBuilder(data, delegate); + return DateTypeOptionBuilder(data, overlayDelegate, dataDelegate); case FieldType.SingleSelect: - return SingleSelectTypeOptionBuilder(field.id, data, delegate); + return SingleSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder(data, delegate); + return MultiSelectTypeOptionBuilder(data, overlayDelegate); case FieldType.Number: - return NumberTypeOptionBuilder(data, delegate); + return NumberTypeOptionBuilder(data, overlayDelegate, dataDelegate); case FieldType.RichText: return RichTextTypeOptionBuilder(data); @@ -163,20 +173,30 @@ abstract class TypeOptionWidget extends StatelessWidget { typedef TypeOptionData = Uint8List; typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData); -typedef ShowOverlayCallback = void Function(BuildContext anchorContext, String overlayIdentifier, Widget child); +typedef ShowOverlayCallback = void Function( + BuildContext anchorContext, + Widget child, { + VoidCallback? onRemoved, +}); typedef HideOverlayCallback = void Function(BuildContext anchorContext); -class TypeOptionOperationDelegate { - TypeOptionDataCallback didUpdateTypeOptionData; - ShowOverlayCallback requireToShowOverlay; +class TypeOptionOverlayDelegate { + ShowOverlayCallback showOverlay; HideOverlayCallback hideOverlay; - TypeOptionOperationDelegate({ - required this.didUpdateTypeOptionData, - required this.requireToShowOverlay, + TypeOptionOverlayDelegate({ + required this.showOverlay, required this.hideOverlay, }); } +class TypeOptionDataDelegate { + TypeOptionDataCallback didUpdateTypeOptionData; + + TypeOptionDataDelegate({ + required this.didUpdateTypeOptionData, + }); +} + class RichTextTypeOptionBuilder extends TypeOptionBuilder { RichTextTypeOption typeOption; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index 0019ffa979..4511a84a1f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -17,22 +17,6 @@ class FieldTypeList extends StatelessWidget { final SelectFieldCallback onSelectField; const FieldTypeList({required this.onSelectField, Key? key}) : super(key: key); - static void show(BuildContext context, SelectFieldCallback onSelectField) { - final list = FieldTypeList(onSelectField: onSelectField); - FieldTypeList.hide(context); - FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer( - child: list, - constraints: BoxConstraints.loose(const Size(140, 300)), - ), - identifier: FieldTypeList.identifier(), - anchorContext: context, - anchorDirection: AnchorDirection.leftWithCenterAligned, - style: FlowyOverlayStyle(blur: false), - anchorOffset: const Offset(-20, 0), - ); - } - static void hide(BuildContext context) { FlowyOverlay.of(context).remove(FieldTypeList.identifier()); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index 493ab0e02e..581a3934e7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -15,30 +15,39 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateTypeOptionBuilder extends TypeOptionBuilder { - DateTypeOption typeOption; - TypeOptionOperationDelegate delegate; + final DateTypeOptionWidget _widget; - DateTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate) - : typeOption = DateTypeOption.fromBuffer(typeOptionData); + DateTypeOptionBuilder( + TypeOptionData typeOptionData, + TypeOptionOverlayDelegate overlayDelegate, + TypeOptionDataDelegate dataDelegate, + ) : _widget = DateTypeOptionWidget( + typeOption: DateTypeOption.fromBuffer(typeOptionData), + dataDelegate: dataDelegate, + overlayDelegate: overlayDelegate, + ); @override - Widget? get customWidget => DateTypeOptionWidget( - typeOption: typeOption, - operationDelegate: delegate, - ); + Widget? get customWidget => _widget; } class DateTypeOptionWidget extends TypeOptionWidget { final DateTypeOption typeOption; - final TypeOptionOperationDelegate operationDelegate; - const DateTypeOptionWidget({required this.typeOption, required this.operationDelegate, Key? key}) : super(key: key); + final TypeOptionOverlayDelegate overlayDelegate; + final TypeOptionDataDelegate dataDelegate; + const DateTypeOptionWidget({ + required this.typeOption, + required this.dataDelegate, + required this.overlayDelegate, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(param1: typeOption), child: BlocConsumer( - listener: (context, state) => operationDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), + listener: (context, state) => dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), builder: (context, state) { return Column(children: [ _dateFormatButton(context), @@ -61,7 +70,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { final list = DateFormatList(onSelected: (format) { context.read().add(DateTypeOptionEvent.didSelectDateFormat(format)); }); - operationDelegate.requireToShowOverlay(context, list.identifier(), list); + overlayDelegate.showOverlay(context, list); }, rightIcon: svg("grid/more", color: theme.iconColor), ), @@ -80,7 +89,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { final list = TimeFormatList(onSelected: (format) { context.read().add(DateTypeOptionEvent.didSelectTimeFormat(format)); }); - operationDelegate.requireToShowOverlay(context, list.identifier(), list); + overlayDelegate.showOverlay(context, list); }, rightIcon: svg("grid/more", color: theme.iconColor), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart index 31f9570602..175f830657 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -1,18 +1,151 @@ +import 'package:app_flowy/workspace/application/grid/field/type_option/edit_option_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; +class EditSelectOptionPannel extends StatelessWidget { + final SelectOption option; + final VoidCallback onDeleted; + final Function(SelectOption) onUpdated; + const EditSelectOptionPannel({ + required this.option, + required this.onDeleted, + required this.onUpdated, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => EditOptionBloc(option: option), + child: MultiBlocListener( + listeners: [ + BlocListener( + listenWhen: (p, c) => p.deleted != c.deleted, + listener: (context, state) { + state.deleted.fold(() => null, (_) => onDeleted()); + }, + ), + BlocListener( + listenWhen: (p, c) => p.option != c.option, + listener: (context, state) { + onUpdated(state.option); + }, + ), + ], + child: BlocBuilder( + builder: (context, state) { + List slivers = [ + SliverToBoxAdapter(child: _OptionNameTextField(state.option.name)), + const SliverToBoxAdapter(child: VSpace(10)), + const SliverToBoxAdapter(child: _DeleteTag()), + const SliverToBoxAdapter(child: TypeOptionSeparator()), + const SliverToBoxAdapter(child: SelectOptionColorList()), + ]; + + return CustomScrollView( + slivers: slivers, + controller: ScrollController(), + physics: StyledScrollPhysics(), + ); + }, + ), + ), + ); + } +} + +class _DeleteTag extends StatelessWidget { + const _DeleteTag({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_selectOption_deleteTag.tr(), fontSize: 12), + hoverColor: theme.hover, + leftIcon: svg("grid/delete", color: theme.iconColor), + onTap: () { + context.read().add(const EditOptionEvent.delete()); + }, + ), + ); + } +} + +class _OptionNameTextField extends StatelessWidget { + final String name; + const _OptionNameTextField(this.name, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return NameTextField( + name: name, + onCanceled: () {}, + onDone: (optionName) { + context.read().add(EditOptionEvent.updateName(optionName)); + }, + ); + } +} + class SelectOptionColorList extends StatelessWidget { const SelectOptionColorList({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return Container(); + final optionItems = SelectOptionColor.values.map((option) { + // Color color = option.color(); + // var hex = option.color.value.toRadixString(16); + // if (hex.startsWith('ff')) { + // hex = hex.substring(2); + // } + // hex = '#$hex'; + + return _SelectOptionColorItem(option: option, isSelected: true); + }).toList(); + + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: GridSize.typeOptionContentInsets, + child: SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyText.medium( + LocaleKeys.grid_selectOption_colorPannelTitle.tr(), + fontSize: 12, + textAlign: TextAlign.left, + ), + ), + ), + ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: optionItems.length, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return optionItems[index]; + }, + ), + ], + ); } } @@ -24,12 +157,12 @@ class _SelectOptionColorItem extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); - Widget? checkmark; if (isSelected) { checkmark = svg("grid/details", color: theme.iconColor); } + final String hex = '#${option.color(context).value.toRadixString(16)}'; final colorIcon = SizedBox.square( dimension: 16, child: Container( @@ -40,15 +173,17 @@ class _SelectOptionColorItem extends StatelessWidget { ), ); - return FlowyButton( - text: FlowyText.medium( - option.name(), - fontSize: 12, + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(option.name(), fontSize: 12), + hoverColor: theme.hover, + leftIcon: colorIcon, + rightIcon: checkmark, + onTap: () { + context.read().add(EditOptionEvent.updateColor(hex)); + }, ), - hoverColor: theme.hover, - leftIcon: colorIcon, - rightIcon: checkmark, - onTap: () {}, ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 4a3694b5fc..43cf2597fa 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -9,7 +9,7 @@ import 'option_pannel.dart'; class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { MultiSelectTypeOption typeOption; - TypeOptionOperationDelegate delegate; + TypeOptionOverlayDelegate delegate; MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate) : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); @@ -20,8 +20,8 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { class MultiSelectTypeOptionWidget extends TypeOptionWidget { final MultiSelectTypeOption typeOption; - final TypeOptionOperationDelegate delegate; - const MultiSelectTypeOptionWidget(this.typeOption, this.delegate, {Key? key}) : super(key: key); + final TypeOptionOverlayDelegate overlayDelegate; + const MultiSelectTypeOptionWidget(this.typeOption, this.overlayDelegate, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -32,14 +32,14 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { return OptionPannel( options: state.typeOption.options, beginEdit: () { - delegate.hideOverlay(context); + overlayDelegate.hideOverlay(context); }, createOptionCallback: (name) { context.read().add(MultiSelectTypeOptionEvent.createOption(name)); }, - updateOptionsCallback: (options) { - context.read().add(MultiSelectTypeOptionEvent.updateOptions(options)); - }, + updateOptionCallback: (updateOption) {}, + deleteOptionCallback: (deleteOption) {}, + overlayDelegate: overlayDelegate, ); }, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index 57a8254f2e..97dffd17e1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -15,25 +15,29 @@ import 'package:easy_localization/easy_localization.dart' hide NumberFormat; import 'package:app_flowy/generated/locale_keys.g.dart'; class NumberTypeOptionBuilder extends TypeOptionBuilder { - NumberTypeOption typeOption; - TypeOptionOperationDelegate delegate; + final NumberTypeOptionWidget _widget; NumberTypeOptionBuilder( TypeOptionData typeOptionData, - this.delegate, - ) : typeOption = NumberTypeOption.fromBuffer(typeOptionData); + TypeOptionOverlayDelegate overlayDelegate, + TypeOptionDataDelegate dataDelegate, + ) : _widget = NumberTypeOptionWidget( + typeOption: NumberTypeOption.fromBuffer(typeOptionData), + dataDelegate: dataDelegate, + overlayDelegate: overlayDelegate, + ); @override - Widget? get customWidget => NumberTypeOptionWidget( - typeOption: typeOption, - operationDelegate: delegate, - ); + Widget? get customWidget => _widget; } class NumberTypeOptionWidget extends TypeOptionWidget { - final TypeOptionOperationDelegate operationDelegate; + final TypeOptionDataDelegate dataDelegate; + final TypeOptionOverlayDelegate overlayDelegate; final NumberTypeOption typeOption; - const NumberTypeOptionWidget({required this.typeOption, required this.operationDelegate, Key? key}) : super(key: key); + const NumberTypeOptionWidget( + {required this.typeOption, required this.dataDelegate, required this.overlayDelegate, Key? key}) + : super(key: key); @override Widget build(BuildContext context) { @@ -43,7 +47,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget { child: SizedBox( height: GridSize.typeOptionItemHeight, child: BlocConsumer( - listener: (context, state) => operationDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), + listener: (context, state) => dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), builder: (context, state) { return FlowyButton( text: FlowyText.medium(LocaleKeys.grid_field_numberFormat.tr(), fontSize: 12), @@ -53,7 +57,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget { final list = NumberFormatList(onSelected: (format) { context.read().add(NumberTypeOptionEvent.didSelectFormat(format)); }); - operationDelegate.requireToShowOverlay(context, list.identifier(), list); + overlayDelegate.showOverlay(context, list); }, rightIcon: svg("grid/more", color: theme.iconColor), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart index 736d03d96d..2c4a1b5e4a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; @@ -11,18 +12,24 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'edit_option_pannel.dart'; import 'widget.dart'; class OptionPannel extends StatelessWidget { final List options; final VoidCallback beginEdit; final Function(String optionName) createOptionCallback; - final Function(List) updateOptionsCallback; + final Function(SelectOption) updateOptionCallback; + final Function(SelectOption) deleteOptionCallback; + final TypeOptionOverlayDelegate overlayDelegate; + const OptionPannel({ required this.options, required this.beginEdit, required this.createOptionCallback, - required this.updateOptionsCallback, + required this.updateOptionCallback, + required this.deleteOptionCallback, + required this.overlayDelegate, Key? key, }) : super(key: key); @@ -39,6 +46,16 @@ class OptionPannel extends StatelessWidget { () => null, (optionName) => createOptionCallback(optionName), ); + + state.updateOption.fold( + () => null, + (updateOption) => updateOptionCallback(updateOption), + ); + + state.deleteOption.fold( + () => null, + (deleteOption) => deleteOptionCallback(deleteOption), + ); }, builder: (context, state) { List children = [ @@ -46,7 +63,7 @@ class OptionPannel extends StatelessWidget { const OptionTitle(), ]; if (state.isEditingOption) { - children.add(const _AddOptionTextField()); + children.add(const _OptionNameTextField()); } if (state.options.isEmpty && !state.isEditingOption) { @@ -54,7 +71,7 @@ class OptionPannel extends StatelessWidget { } if (state.options.isNotEmpty) { - children.add(_OptionList(key: ObjectKey(state.options))); + children.add(_OptionList(overlayDelegate)); } return Column(children: children); @@ -105,14 +122,18 @@ class OptionTitle extends StatelessWidget { } class _OptionList extends StatelessWidget { - const _OptionList({Key? key}) : super(key: key); + final TypeOptionOverlayDelegate delegate; + const _OptionList(this.delegate, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocBuilder( + buildWhen: (previous, current) { + return previous.options != current.options; + }, builder: (context, state) { final optionItems = state.options.map((option) { - return _OptionItem(option: option); + return _makeOptionItem(context, option); }).toList(); return ListView.separated( @@ -129,11 +150,37 @@ class _OptionList extends StatelessWidget { }, ); } + + _OptionItem _makeOptionItem(BuildContext context, SelectOption option) { + return _OptionItem( + option: option, + onEdited: (option) { + final pannel = EditSelectOptionPannel( + option: option, + onDeleted: () { + delegate.hideOverlay(context); + context.read().add(OptionPannelEvent.deleteOption(option)); + }, + onUpdated: (updatedOption) { + delegate.hideOverlay(context); + context.read().add(OptionPannelEvent.updateOption(updatedOption)); + }, + key: ValueKey(option.id), + ); + delegate.showOverlay(context, pannel); + }, + ); + } } class _OptionItem extends StatelessWidget { final SelectOption option; - const _OptionItem({required this.option, Key? key}) : super(key: key); + final Function(SelectOption) onEdited; + const _OptionItem({ + required this.option, + required this.onEdited, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -143,7 +190,7 @@ class _OptionItem extends StatelessWidget { child: FlowyButton( text: FlowyText.medium(option.name, fontSize: 12), hoverColor: theme.hover, - onTap: () {}, + onTap: () => onEdited(option), rightIcon: svg("grid/details", color: theme.iconColor), ), ); @@ -170,8 +217,8 @@ class _AddOptionButton extends StatelessWidget { } } -class _AddOptionTextField extends StatelessWidget { - const _AddOptionTextField({Key? key}) : super(key: key); +class _OptionNameTextField extends StatelessWidget { + const _OptionNameTextField({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart index 6690729ff0..76573ef945 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -12,11 +12,13 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { SingleSelectTypeOptionBuilder( String fieldId, TypeOptionData typeOptionData, - TypeOptionOperationDelegate delegate, + TypeOptionOverlayDelegate overlayDelegate, + TypeOptionDataDelegate dataDelegate, ) : _widget = SingleSelectTypeOptionWidget( - fieldId, - SingleSelectTypeOption.fromBuffer(typeOptionData), - delegate, + fieldId: fieldId, + typeOption: SingleSelectTypeOption.fromBuffer(typeOptionData), + dataDelegate: dataDelegate, + overlayDelegate: overlayDelegate, ); @override @@ -26,27 +28,41 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { class SingleSelectTypeOptionWidget extends TypeOptionWidget { final String fieldId; final SingleSelectTypeOption typeOption; - final TypeOptionOperationDelegate delegate; - const SingleSelectTypeOptionWidget(this.fieldId, this.typeOption, this.delegate, {Key? key}) : super(key: key); + final TypeOptionOverlayDelegate overlayDelegate; + final TypeOptionDataDelegate dataDelegate; + const SingleSelectTypeOptionWidget({ + required this.fieldId, + required this.typeOption, + required this.dataDelegate, + required this.overlayDelegate, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => getIt(param1: typeOption, param2: fieldId), child: BlocConsumer( - listener: (context, state) => delegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), + listener: (context, state) { + dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); + }, builder: (context, state) { return OptionPannel( options: state.typeOption.options, beginEdit: () { - delegate.hideOverlay(context); + overlayDelegate.hideOverlay(context); }, createOptionCallback: (name) { context.read().add(SingleSelectTypeOptionEvent.createOption(name)); }, - updateOptionsCallback: (options) { - context.read().add(SingleSelectTypeOptionEvent.updateOptions(options)); + updateOptionCallback: (updateOption) { + context.read().add(SingleSelectTypeOptionEvent.updateOption(updateOption)); }, + deleteOptionCallback: (deleteOption) { + context.read().add(SingleSelectTypeOptionEvent.deleteOption(deleteOption)); + }, + overlayDelegate: overlayDelegate, + key: ValueKey(state.typeOption.hashCode), ); }, ), From 4b27fef76e3ddcfd48c1e6ca2101323f2a46b557 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 31 Mar 2022 14:43:31 +0800 Subject: [PATCH 076/179] chore: select option color --- .../field/type_option/edit_option_bloc.dart | 66 ++++++++++ .../menu/app/header/right_click_action.dart | 2 +- .../menu/app/section/disclosure_action.dart | 4 +- .../presentation/plugins/doc/document.dart | 2 +- .../widgets/header/create_field_pannel.dart | 3 + .../type_option/edit_option_pannel.dart | 94 ++++++-------- .../widgets/float_bubble/question_bubble.dart | 2 +- .../lib/src/flowy_overlay/flowy_overlay.dart | 50 ++++++-- .../flowy-grid/selection_type_option.pb.dart | 12 +- .../selection_type_option.pbenum.dart | 33 +++++ .../selection_type_option.pbjson.dart | 22 +++- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-grid/Cargo.toml | 1 + .../protobuf/model/selection_type_option.rs | 120 ++++++++++++++---- .../proto/selection_type_option.proto | 13 +- .../type_options/selection_type_option.rs | 26 +++- 16 files changed, 343 insertions(+), 108 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart new file mode 100644 index 0000000000..ccd0c47bab --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart @@ -0,0 +1,66 @@ +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:protobuf/protobuf.dart'; +import 'package:dartz/dartz.dart'; +part 'edit_option_bloc.freezed.dart'; + +class EditOptionBloc extends Bloc { + EditOptionBloc({required SelectOption option}) : super(EditOptionState.initial(option)) { + on( + (event, emit) async { + event.map( + updateName: (_UpdateName value) { + emit(state.copyWith(option: _updateName(value.name))); + }, + updateColor: (_UpdateColor value) { + emit(state.copyWith(option: _updateColor(value.color))); + }, + delete: (_Delete value) { + emit(state.copyWith(deleted: const Some(true))); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } + + SelectOption _updateColor(SelectOptionColor color) { + state.option.freeze(); + return state.option.rebuild((option) { + option.color = color; + }); + } + + SelectOption _updateName(String name) { + state.option.freeze(); + return state.option.rebuild((option) { + option.name = name; + }); + } +} + +@freezed +class EditOptionEvent with _$EditOptionEvent { + const factory EditOptionEvent.updateName(String name) = _UpdateName; + const factory EditOptionEvent.updateColor(SelectOptionColor color) = _UpdateColor; + const factory EditOptionEvent.delete() = _Delete; +} + +@freezed +class EditOptionState with _$EditOptionState { + const factory EditOptionState({ + required SelectOption option, + required Option deleted, + }) = _EditOptionState; + + factory EditOptionState.initial(SelectOption option) => EditOptionState( + option: option, + deleted: none(), + ); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart index 8938443236..be6a97dbfb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; import 'header.dart'; -class AppDisclosureActionSheet with ActionList implements FlowyOverlayDelegate { +class AppDisclosureActionSheet with ActionList, FlowyOverlayDelegate { final Function(dartz.Option) onSelected; final _items = AppDisclosureAction.values.map((action) => DisclosureActionWrapper(action)).toList(); diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart index cf66476ab8..a706ae5019 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart @@ -11,9 +11,7 @@ import 'item.dart'; // [[Widget: LifeCycle]] // https://flutterbyexample.com/lesson/stateful-widget-lifecycle -class ViewDisclosureButton extends StatelessWidget - with ActionList - implements FlowyOverlayDelegate { +class ViewDisclosureButton extends StatelessWidget with ActionList, FlowyOverlayDelegate { final Function() onTap; final Function(dartz.Option) onSelected; final _items = ViewDisclosureAction.values.map((action) => ViewDisclosureActionWrapper(action)).toList(); 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 83e577ec10..b0727bb73a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -195,7 +195,7 @@ class DocumentShareButton extends StatelessWidget { } } -class ShareActions with ActionList implements FlowyOverlayDelegate { +class ShareActions with ActionList, FlowyOverlayDelegate { final Function(dartz.Option) onSelected; final _items = ShareAction.values.map((action) => ShareActionWrapper(action)).toList(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart index 8b2b74d9ae..a530737e28 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart @@ -38,6 +38,9 @@ class CreateFieldPannel extends FlowyOverlayDelegate { void didRemove() { _createFieldBloc.add(const CreateFieldEvent.done()); } + + @override + bool asBarrier() => true; } class _CreateFieldPannelWidget extends StatelessWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart index 175f830657..e7999b7e4c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -50,13 +50,16 @@ class EditSelectOptionPannel extends StatelessWidget { const SliverToBoxAdapter(child: VSpace(10)), const SliverToBoxAdapter(child: _DeleteTag()), const SliverToBoxAdapter(child: TypeOptionSeparator()), - const SliverToBoxAdapter(child: SelectOptionColorList()), + SliverToBoxAdapter(child: SelectOptionColorList(selectedColor: state.option.color)), ]; - return CustomScrollView( - slivers: slivers, - controller: ScrollController(), - physics: StyledScrollPhysics(), + return SizedBox( + width: 160, + child: CustomScrollView( + slivers: slivers, + controller: ScrollController(), + physics: StyledScrollPhysics(), + ), ); }, ), @@ -102,19 +105,13 @@ class _OptionNameTextField extends StatelessWidget { } class SelectOptionColorList extends StatelessWidget { - const SelectOptionColorList({Key? key}) : super(key: key); + final SelectOptionColor selectedColor; + const SelectOptionColorList({required this.selectedColor, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final optionItems = SelectOptionColor.values.map((option) { - // Color color = option.color(); - // var hex = option.color.value.toRadixString(16); - // if (hex.startsWith('ff')) { - // hex = hex.substring(2); - // } - // hex = '#$hex'; - - return _SelectOptionColorItem(option: option, isSelected: true); + final optionItems = SelectOptionColor.values.map((color) { + return _SelectOptionColorItem(color: color, isSelected: selectedColor == color); }).toList(); return Column( @@ -150,24 +147,23 @@ class SelectOptionColorList extends StatelessWidget { } class _SelectOptionColorItem extends StatelessWidget { - final SelectOptionColor option; + final SelectOptionColor color; final bool isSelected; - const _SelectOptionColorItem({required this.option, required this.isSelected, Key? key}) : super(key: key); + const _SelectOptionColorItem({required this.color, required this.isSelected, Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); Widget? checkmark; if (isSelected) { - checkmark = svg("grid/details", color: theme.iconColor); + checkmark = svg("grid/checkmark"); } - final String hex = '#${option.color(context).value.toRadixString(16)}'; final colorIcon = SizedBox.square( dimension: 16, child: Container( decoration: BoxDecoration( - color: option.color(context), + color: color.color(context), shape: BoxShape.circle, ), ), @@ -176,75 +172,67 @@ class _SelectOptionColorItem extends StatelessWidget { return SizedBox( height: GridSize.typeOptionItemHeight, child: FlowyButton( - text: FlowyText.medium(option.name(), fontSize: 12), + text: FlowyText.medium(color.optionName(), fontSize: 12), hoverColor: theme.hover, leftIcon: colorIcon, rightIcon: checkmark, onTap: () { - context.read().add(EditOptionEvent.updateColor(hex)); + context.read().add(EditOptionEvent.updateColor(color)); }, ), ); } } -enum SelectOptionColor { - purple, - pink, - lightPink, - orange, - yellow, - lime, - green, - aqua, - blue, -} - extension SelectOptionColorExtension on SelectOptionColor { Color color(BuildContext context) { final theme = context.watch(); switch (this) { - case SelectOptionColor.purple: + case SelectOptionColor.Purple: return theme.tint1; - case SelectOptionColor.pink: + case SelectOptionColor.Pink: return theme.tint2; - case SelectOptionColor.lightPink: + case SelectOptionColor.LightPink: return theme.tint3; - case SelectOptionColor.orange: + case SelectOptionColor.Orange: return theme.tint4; - case SelectOptionColor.yellow: + case SelectOptionColor.Yellow: return theme.tint5; - case SelectOptionColor.lime: + case SelectOptionColor.Lime: return theme.tint6; - case SelectOptionColor.green: + case SelectOptionColor.Green: return theme.tint7; - case SelectOptionColor.aqua: + case SelectOptionColor.Aqua: return theme.tint8; - case SelectOptionColor.blue: + case SelectOptionColor.Blue: return theme.tint9; + default: + throw ArgumentError; } } - String name() { + String optionName() { switch (this) { - case SelectOptionColor.purple: + case SelectOptionColor.Purple: return LocaleKeys.grid_selectOption_purpleColor.tr(); - case SelectOptionColor.pink: + case SelectOptionColor.Pink: return LocaleKeys.grid_selectOption_pinkColor.tr(); - case SelectOptionColor.lightPink: + case SelectOptionColor.LightPink: return LocaleKeys.grid_selectOption_lightPinkColor.tr(); - case SelectOptionColor.orange: + case SelectOptionColor.Orange: return LocaleKeys.grid_selectOption_orangeColor.tr(); - case SelectOptionColor.yellow: + case SelectOptionColor.Yellow: return LocaleKeys.grid_selectOption_yellowColor.tr(); - case SelectOptionColor.lime: + case SelectOptionColor.Lime: return LocaleKeys.grid_selectOption_limeColor.tr(); - case SelectOptionColor.green: + case SelectOptionColor.Green: return LocaleKeys.grid_selectOption_greenColor.tr(); - case SelectOptionColor.aqua: + case SelectOptionColor.Aqua: return LocaleKeys.grid_selectOption_aquaColor.tr(); - case SelectOptionColor.blue: + case SelectOptionColor.Blue: return LocaleKeys.grid_selectOption_blueColor.tr(); + default: + throw ArgumentError; } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart index 239918994e..3309566eaf 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart @@ -130,7 +130,7 @@ class QuestionBubble extends StatelessWidget { } } -class QuestionBubbleActionSheet with ActionList implements FlowyOverlayDelegate { +class QuestionBubbleActionSheet with ActionList, FlowyOverlayDelegate { final Function(dartz.Option) onSelected; final _items = BubbleAction.values.map((action) => BubbleActionWrapper(action)).toList(); diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 651971d17f..99d86d22bb 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -1,10 +1,8 @@ // ignore_for_file: unused_element -import 'package:dartz/dartz.dart' show Tuple3; +import 'dart:ui'; import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart'; import 'package:flutter/material.dart'; -import 'dart:ui'; - export './overlay_container.dart'; /// Specifies how overlay are anchored to the SourceWidget @@ -75,6 +73,7 @@ TransitionBuilder overlayManagerBuilder() { } abstract class FlowyOverlayDelegate { + bool asBarrier() => false; void didRemove(); } @@ -110,8 +109,20 @@ class FlowyOverlay extends StatefulWidget { FlowyOverlayState createState() => FlowyOverlayState(); } +class OverlayItem { + Widget widget; + String identifier; + FlowyOverlayDelegate? delegate; + + OverlayItem({ + required this.widget, + required this.identifier, + this.delegate, + }); +} + class FlowyOverlayState extends State { - List> _overlayList = []; + List _overlayList = []; FlowyOverlayStyle style = FlowyOverlayStyle(); /// Insert a overlay widget which frame is set by the widget, not the component. @@ -181,19 +192,32 @@ class FlowyOverlayState extends State { void remove(String identifier) { setState(() { - final index = _overlayList.indexWhere((ele) => ele.value2 == identifier); + final index = _overlayList.indexWhere((item) => item.identifier == identifier); if (index != -1) { - _overlayList.removeAt(index).value3?.didRemove(); + _overlayList.removeAt(index).delegate?.didRemove(); } }); } void removeAll() { setState(() { - for (var ele in _overlayList.reversed) { - ele.value3?.didRemove(); + if (_overlayList.isEmpty) { + return; + } + + final reveredList = _overlayList.reversed.toList(); + final firstItem = reveredList.removeAt(0); + firstItem.delegate?.didRemove(); + _overlayList.remove(firstItem); + + for (final element in reveredList) { + if (element.delegate?.asBarrier() ?? false) { + return; + } else { + element.delegate?.didRemove(); + _overlayList.remove(element); + } } - _overlayList = []; }); } @@ -252,13 +276,17 @@ class FlowyOverlayState extends State { } setState(() { - _overlayList.add(Tuple3(overlay, identifier, delegate)); + _overlayList.add(OverlayItem( + widget: overlay, + identifier: identifier, + delegate: delegate, + )); }); } @override Widget build(BuildContext context) { - final overlays = _overlayList.map((ele) => ele.value1); + final overlays = _overlayList.map((item) => item.widget); List children = [widget.child]; Widget? child; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart index f2222d82b8..2e1ac9610e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -9,6 +9,10 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'selection_type_option.pbenum.dart'; + +export 'selection_type_option.pbenum.dart'; + class SingleSelectTypeOption extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectTypeOption', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) @@ -123,7 +127,7 @@ 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') + ..e(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color', $pb.PbFieldType.OE, defaultOrMaker: SelectOptionColor.Purple, valueOf: SelectOptionColor.valueOf, enumValues: SelectOptionColor.values) ..hasRequiredFields = false ; @@ -131,7 +135,7 @@ class SelectOption extends $pb.GeneratedMessage { factory SelectOption({ $core.String? id, $core.String? name, - $core.String? color, + SelectOptionColor? color, }) { final _result = create(); if (id != null) { @@ -185,9 +189,9 @@ class SelectOption extends $pb.GeneratedMessage { void clearName() => clearField(2); @$pb.TagNumber(3) - $core.String get color => $_getSZ(2); + SelectOptionColor get color => $_getN(2); @$pb.TagNumber(3) - set color($core.String v) { $_setString(2, v); } + set color(SelectOptionColor v) { setField(3, v); } @$pb.TagNumber(3) $core.bool hasColor() => $_has(2); @$pb.TagNumber(3) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart index 9a52c17f7d..0a063abf16 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbenum.dart @@ -5,3 +5,36 @@ // @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 SelectOptionColor extends $pb.ProtobufEnum { + static const SelectOptionColor Purple = SelectOptionColor._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Purple'); + static const SelectOptionColor Pink = SelectOptionColor._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Pink'); + static const SelectOptionColor LightPink = SelectOptionColor._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'LightPink'); + static const SelectOptionColor Orange = SelectOptionColor._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Orange'); + static const SelectOptionColor Yellow = SelectOptionColor._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Yellow'); + static const SelectOptionColor Lime = SelectOptionColor._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Lime'); + static const SelectOptionColor Green = SelectOptionColor._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Green'); + static const SelectOptionColor Aqua = SelectOptionColor._(7, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Aqua'); + static const SelectOptionColor Blue = SelectOptionColor._(8, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Blue'); + + static const $core.List values = [ + Purple, + Pink, + LightPink, + Orange, + Yellow, + Lime, + Green, + Aqua, + Blue, + ]; + + static final $core.Map<$core.int, SelectOptionColor> _byValue = $pb.ProtobufEnum.initByValue(values); + static SelectOptionColor? valueOf($core.int value) => _byValue[value]; + + const SelectOptionColor._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart index fdfc6833b0..7499864079 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -8,6 +8,24 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use selectOptionColorDescriptor instead') +const SelectOptionColor$json = const { + '1': 'SelectOptionColor', + '2': const [ + const {'1': 'Purple', '2': 0}, + const {'1': 'Pink', '2': 1}, + const {'1': 'LightPink', '2': 2}, + const {'1': 'Orange', '2': 3}, + const {'1': 'Yellow', '2': 4}, + const {'1': 'Lime', '2': 5}, + const {'1': 'Green', '2': 6}, + const {'1': 'Aqua', '2': 7}, + const {'1': 'Blue', '2': 8}, + ], +}; + +/// Descriptor for `SelectOptionColor`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List selectOptionColorDescriptor = $convert.base64Decode('ChFTZWxlY3RPcHRpb25Db2xvchIKCgZQdXJwbGUQABIICgRQaW5rEAESDQoJTGlnaHRQaW5rEAISCgoGT3JhbmdlEAMSCgoGWWVsbG93EAQSCAoETGltZRAFEgkKBUdyZWVuEAYSCAoEQXF1YRAHEggKBEJsdWUQCA=='); @$core.Deprecated('Use singleSelectTypeOptionDescriptor instead') const SingleSelectTypeOption$json = const { '1': 'SingleSelectTypeOption', @@ -36,9 +54,9 @@ const SelectOption$json = const { '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'}, + const {'1': 'color', '3': 3, '4': 1, '5': 14, '6': '.SelectOptionColor', '10': 'color'}, ], }; /// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); +final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSKAoFY29sb3IYAyABKA4yEi5TZWxlY3RPcHRpb25Db2xvclIFY29sb3I='); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index e99f1b541b..1a996b2a43 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -956,6 +956,7 @@ dependencies = [ "rusty-money", "serde", "serde_json", + "serde_repr", "strum", "strum_macros", "tokio", diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 3549bedd08..de0320f062 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -33,6 +33,7 @@ tokio = {version = "1", features = ["sync"]} rayon = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} +serde_repr = "0.1" [dev-dependencies] flowy-test = { path = "../flowy-test" } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index 6d12dbc81f..ae57224d2e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -430,7 +430,7 @@ pub struct SelectOption { // message fields pub id: ::std::string::String, pub name: ::std::string::String, - pub color: ::std::string::String, + pub color: SelectOptionColor, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -499,31 +499,20 @@ impl SelectOption { ::std::mem::replace(&mut self.name, ::std::string::String::new()) } - // string color = 3; + // .SelectOptionColor color = 3; - pub fn get_color(&self) -> &str { - &self.color + pub fn get_color(&self) -> SelectOptionColor { + self.color } pub fn clear_color(&mut self) { - self.color.clear(); + self.color = SelectOptionColor::Purple; } // Param is passed by value, moved - pub fn set_color(&mut self, v: ::std::string::String) { + pub fn set_color(&mut self, v: SelectOptionColor) { 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 { @@ -542,7 +531,7 @@ impl ::protobuf::Message for SelectOption { ::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_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.color, 3, &mut self.unknown_fields)? }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -562,8 +551,8 @@ impl ::protobuf::Message for SelectOption { 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); + if self.color != SelectOptionColor::Purple { + my_size += ::protobuf::rt::enum_size(3, self.color); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -577,8 +566,8 @@ impl ::protobuf::Message for SelectOption { if !self.name.is_empty() { os.write_string(2, &self.name)?; } - if !self.color.is_empty() { - os.write_string(3, &self.color)?; + if self.color != SelectOptionColor::Purple { + os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.color))?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -628,7 +617,7 @@ impl ::protobuf::Message for SelectOption { |m: &SelectOption| { &m.name }, |m: &mut SelectOption| { &mut m.name }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "color", |m: &SelectOption| { &m.color }, |m: &mut SelectOption| { &mut m.color }, @@ -651,7 +640,7 @@ impl ::protobuf::Clear for SelectOption { fn clear(&mut self) { self.id.clear(); self.name.clear(); - self.color.clear(); + self.color = SelectOptionColor::Purple; self.unknown_fields.clear(); } } @@ -668,15 +657,90 @@ impl ::protobuf::reflect::ProtobufValue for SelectOption { } } +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum SelectOptionColor { + Purple = 0, + Pink = 1, + LightPink = 2, + Orange = 3, + Yellow = 4, + Lime = 5, + Green = 6, + Aqua = 7, + Blue = 8, +} + +impl ::protobuf::ProtobufEnum for SelectOptionColor { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(SelectOptionColor::Purple), + 1 => ::std::option::Option::Some(SelectOptionColor::Pink), + 2 => ::std::option::Option::Some(SelectOptionColor::LightPink), + 3 => ::std::option::Option::Some(SelectOptionColor::Orange), + 4 => ::std::option::Option::Some(SelectOptionColor::Yellow), + 5 => ::std::option::Option::Some(SelectOptionColor::Lime), + 6 => ::std::option::Option::Some(SelectOptionColor::Green), + 7 => ::std::option::Option::Some(SelectOptionColor::Aqua), + 8 => ::std::option::Option::Some(SelectOptionColor::Blue), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [SelectOptionColor] = &[ + SelectOptionColor::Purple, + SelectOptionColor::Pink, + SelectOptionColor::LightPink, + SelectOptionColor::Orange, + SelectOptionColor::Yellow, + SelectOptionColor::Lime, + SelectOptionColor::Green, + SelectOptionColor::Aqua, + SelectOptionColor::Blue, + ]; + 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::("SelectOptionColor", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for SelectOptionColor { +} + +impl ::std::default::Default for SelectOptionColor { + fn default() -> Self { + SelectOptionColor::Purple + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionColor { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\x1bselection_type_option.proto\"f\n\x16SingleSelectTypeOption\x12'\n\ \x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdis\ able_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"e\n\x15MultiSelectType\ Option\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07option\ - s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cSe\ - lectOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ - \x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05c\ - olorb\x06proto3\ + s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"\\\n\x0cS\ + electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ + \x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\x18\x03\x20\x01(\x0e2\x12.S\ + electOptionColorR\x05color*y\n\x11SelectOptionColor\x12\n\n\x06Purple\ + \x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightPink\x10\x02\x12\n\n\x06O\ + range\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\n\x04Lime\x10\x05\x12\t\ + \n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\x12\x08\n\x04Blue\x10\x08b\ + \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/selection_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index 9fdfc34e9b..f07e2273bb 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -11,5 +11,16 @@ message MultiSelectTypeOption { message SelectOption { string id = 1; string name = 2; - string color = 3; + SelectOptionColor color = 3; +} +enum SelectOptionColor { + Purple = 0; + Pink = 1; + LightPink = 2; + Orange = 3; + Yellow = 4; + Lime = 5; + Green = 6; + Aqua = 7; + Blue = 8; } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 73dd3bd432..015bf2257b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -3,7 +3,7 @@ use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; use crate::services::util::*; use bytes::Bytes; -use flowy_derive::ProtoBuf; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -151,7 +151,7 @@ pub struct SelectOption { pub name: String, #[pb(index = 3)] - pub color: String, + pub color: SelectOptionColor, } impl SelectOption { @@ -159,11 +159,31 @@ impl SelectOption { SelectOption { id: uuid(), name: name.to_owned(), - color: "".to_string(), + color: SelectOptionColor::default(), } } } +#[derive(ProtoBuf_Enum, Serialize, Deserialize, Debug, Clone)] +#[repr(u8)] +pub enum SelectOptionColor { + Purple = 0, + Pink = 1, + LightPink = 2, + Orange = 3, + Yellow = 4, + Lime = 5, + Green = 6, + Aqua = 7, + Blue = 8, +} + +impl std::default::Default for SelectOptionColor { + fn default() -> Self { + SelectOptionColor::Purple + } +} + #[cfg(test)] mod tests { use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption}; From 7c6a857a699646eeeddcbb6e521236bca2445463 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 31 Mar 2022 14:59:57 +0800 Subject: [PATCH 077/179] chore: multi select --- .../assets/images/grid/checkmark.svg | 3 + .../app_flowy/lib/startup/deps_resolver.dart | 4 +- .../field/type_option/multi_select_bloc.dart | 57 +++++++++++++++++-- .../widgets/header/field_tyep_switcher.dart | 2 +- .../header/type_option/multi_select.dart | 44 ++++++++++---- 5 files changed, 92 insertions(+), 18 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/checkmark.svg diff --git a/frontend/app_flowy/assets/images/grid/checkmark.svg b/frontend/app_flowy/assets/images/grid/checkmark.svg new file mode 100644 index 0000000000..f9c848f713 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/checkmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 8bab77150a..4cb0fda104 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -221,8 +221,8 @@ void _resolveGridDeps(GetIt getIt) { (typeOption, fieldId) => SingleSelectTypeOptionBloc(typeOption, fieldId), ); - getIt.registerFactoryParam( - (typeOption, _) => MultiSelectTypeOptionBloc(typeOption), + getIt.registerFactoryParam( + (typeOption, fieldId) => MultiSelectTypeOptionBloc(typeOption, fieldId), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart index 75ac80c47c..0a96f5f69b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart @@ -1,18 +1,37 @@ -import 'dart:typed_data'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; +import 'package:protobuf/protobuf.dart'; +import 'type_option_service.dart'; part 'multi_select_bloc.freezed.dart'; class MultiSelectTypeOptionBloc extends Bloc { - MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption) : super(MultiSelectTypeOptionState.initial(typeOption)) { + final TypeOptionService service; + + MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption, String fieldId) + : service = TypeOptionService(fieldId: fieldId), + super(MultiSelectTypeOptionState.initial(typeOption)) { on( (event, emit) async { await event.map( - createOption: (_CreateOption value) {}, - updateOptions: (_UpdateOptions value) async {}, + createOption: (_CreateOption value) async { + final result = await service.createOption(value.optionName); + result.fold( + (option) { + emit(state.copyWith(typeOption: _insertOption(option))); + }, + (err) => Log.error(err), + ); + }, + updateOption: (_UpdateOption value) async { + emit(state.copyWith(typeOption: _updateOption(value.option))); + }, + deleteOption: (_DeleteOption value) { + emit(state.copyWith(typeOption: _deleteOption(value.option))); + }, ); }, ); @@ -22,12 +41,40 @@ class MultiSelectTypeOptionBloc extends Bloc close() async { return super.close(); } + + MultiSelectTypeOption _insertOption(SelectOption option) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + typeOption.options.insert(0, option); + }); + } + + MultiSelectTypeOption _updateOption(SelectOption option) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + final index = typeOption.options.indexWhere((element) => element.id == option.id); + if (index != -1) { + typeOption.options[index] = option; + } + }); + } + + MultiSelectTypeOption _deleteOption(SelectOption option) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + final index = typeOption.options.indexWhere((element) => element.id == option.id); + if (index != -1) { + typeOption.options.removeAt(index); + } + }); + } } @freezed class MultiSelectTypeOptionEvent with _$MultiSelectTypeOptionEvent { const factory MultiSelectTypeOptionEvent.createOption(String optionName) = _CreateOption; - const factory MultiSelectTypeOptionEvent.updateOptions(List options) = _UpdateOptions; + const factory MultiSelectTypeOptionEvent.updateOption(SelectOption option) = _UpdateOption; + const factory MultiSelectTypeOptionEvent.deleteOption(SelectOption option) = _DeleteOption; } @freezed diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart index ce34097118..e8eb5caee2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart @@ -156,7 +156,7 @@ TypeOptionBuilder _makeTypeOptionBuild({ case FieldType.SingleSelect: return SingleSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder(data, overlayDelegate); + return MultiSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); case FieldType.Number: return NumberTypeOptionBuilder(data, overlayDelegate, dataDelegate); case FieldType.RichText: diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 43cf2597fa..23881e9310 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -8,26 +8,45 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'option_pannel.dart'; class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { - MultiSelectTypeOption typeOption; - TypeOptionOverlayDelegate delegate; + MultiSelectTypeOptionWidget _widget; - MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate) - : typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData); + MultiSelectTypeOptionBuilder( + String fieldId, + TypeOptionData typeOptionData, + TypeOptionOverlayDelegate overlayDelegate, + TypeOptionDataDelegate dataDelegate, + ) : _widget = MultiSelectTypeOptionWidget( + fieldId: fieldId, + typeOption: MultiSelectTypeOption.fromBuffer(typeOptionData), + overlayDelegate: overlayDelegate, + dataDelegate: dataDelegate, + ); @override - Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption, delegate); + Widget? get customWidget => _widget; } class MultiSelectTypeOptionWidget extends TypeOptionWidget { + final String fieldId; final MultiSelectTypeOption typeOption; final TypeOptionOverlayDelegate overlayDelegate; - const MultiSelectTypeOptionWidget(this.typeOption, this.overlayDelegate, {Key? key}) : super(key: key); + final TypeOptionDataDelegate dataDelegate; + const MultiSelectTypeOptionWidget({ + required this.fieldId, + required this.typeOption, + required this.overlayDelegate, + required this.dataDelegate, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: typeOption), - child: BlocBuilder( + create: (context) => getIt(param1: typeOption, param2: fieldId), + child: BlocConsumer( + listener: (context, state) { + dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); + }, builder: (context, state) { return OptionPannel( options: state.typeOption.options, @@ -37,9 +56,14 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { createOptionCallback: (name) { context.read().add(MultiSelectTypeOptionEvent.createOption(name)); }, - updateOptionCallback: (updateOption) {}, - deleteOptionCallback: (deleteOption) {}, + updateOptionCallback: (updateOption) { + context.read().add(MultiSelectTypeOptionEvent.updateOption(updateOption)); + }, + deleteOptionCallback: (deleteOption) { + context.read().add(MultiSelectTypeOptionEvent.deleteOption(deleteOption)); + }, overlayDelegate: overlayDelegate, + key: ValueKey(state.typeOption.hashCode), ); }, ), From c3c75dde9fcab43150f7a5322bbcdb744cd86bf0 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 31 Mar 2022 19:45:54 +0800 Subject: [PATCH 078/179] chore: show edit field --- .../grid/field/type_option/date_bloc.dart | 22 +++- .../grid/field/type_option/number_bloc.dart | 11 +- .../src/widgets/header/edit_field_pannel.dart | 110 ------------------ .../src/widgets/header/grid_header_cell.dart | 4 +- .../src/widgets/header/type_option/date.dart | 67 ++++++++--- 5 files changed, 80 insertions(+), 134 deletions(-) delete mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart index e2e7f2f0e2..0cf842a171 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -2,7 +2,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; - +import 'package:protobuf/protobuf.dart'; part 'date_bloc.freezed.dart'; class DateTypeOptionBloc extends Bloc { @@ -11,18 +11,30 @@ class DateTypeOptionBloc extends Bloc (event, emit) async { event.map( didSelectDateFormat: (_DidSelectDateFormat value) { - state.typeOption.dateFormat = value.format; - emit(state); + emit(state.copyWith(typeOption: _updateDateFormat(value.format))); }, didSelectTimeFormat: (_DidSelectTimeFormat value) { - state.typeOption.timeFormat = value.format; - emit(state); + emit(state.copyWith(typeOption: _updateTimeFormat(value.format))); }, ); }, ); } + DateTypeOption _updateTimeFormat(TimeFormat format) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + typeOption.timeFormat = format; + }); + } + + DateTypeOption _updateDateFormat(DateFormat format) { + state.typeOption.freeze(); + return state.typeOption.rebuild((typeOption) { + typeOption.dateFormat = format; + }); + } + @override Future close() async { return super.close(); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart index a396454671..a655ebc1e8 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart @@ -2,6 +2,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; +import 'package:protobuf/protobuf.dart'; part 'number_bloc.freezed.dart'; @@ -11,14 +12,20 @@ class NumberTypeOptionBloc extends Bloc close() async { return super.close(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart deleted file mode 100644 index cab5a51138..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import 'field_name_input.dart'; -import 'field_operation_list.dart'; -import 'field_tyep_switcher.dart'; - -class EditFieldPannel extends StatelessWidget { - final GridFieldData fieldData; - const EditFieldPannel({required this.fieldData, Key? key}) : super(key: key); - - static void show(BuildContext context, GridFieldData fieldData) { - final editor = EditFieldPannel(fieldData: fieldData); - FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer( - child: editor, - constraints: BoxConstraints.loose(const Size(300, 200)), - ), - identifier: editor.identifier(), - anchorContext: context, - anchorDirection: AnchorDirection.bottomWithLeftAligned, - ); - } - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: fieldData)..add(const EditFieldEvent.initial()), - child: SingleChildScrollView( - child: Column( - children: [ - const _FieldNameTextField(), - const VSpace(6), - const _FieldTypeSwitcher(), - const VSpace(6), - _FieldOperationList(fieldData, () => FlowyOverlay.of(context).remove(identifier())), - ], - ), - ), - ); - } - - String identifier() { - return toString(); - } -} - -class _FieldOperationList extends StatelessWidget { - final GridFieldData fieldData; - final VoidCallback onDismissed; - const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final actions = FieldAction.values - .map( - (action) => FieldActionItem( - fieldId: fieldData.field.id, - action: action, - onTap: onDismissed, - ), - ) - .toList(); - - return FieldOperationList(actions: actions); - } -} - -class _FieldTypeSwitcher extends StatelessWidget { - const _FieldTypeSwitcher({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - final editContext = context.read().state.editContext; - final switchContext = SwitchFieldContext( - editContext.gridId, - editContext.gridField, - editContext.typeOptionData, - ); - return FieldTypeSwitcher(switchContext: switchContext, onSelected: (field, typeOptionData) {}); - }, - ); - } -} - -class _FieldNameTextField extends StatelessWidget { - const _FieldNameTextField({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: ((previous, current) => previous.fieldName == current.fieldName), - builder: (context, state) { - return FieldNameTextField( - name: state.fieldName, - errorText: state.errorText, - onNameChanged: (newName) { - context.read().add(EditFieldEvent.updateFieldName(newName)); - }, - ); - }, - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart index 5e5dc5f4fd..19869ccffc 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart @@ -7,7 +7,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'edit_field_pannel.dart'; +import 'field_detail_pannel.dart'; class GridHeaderCell extends StatelessWidget { final GridFieldData fieldData; @@ -18,7 +18,7 @@ class GridHeaderCell extends StatelessWidget { final theme = context.watch(); final button = FlowyButton( hoverColor: theme.hover, - onTap: () => EditFieldPannel.show(context, fieldData), + onTap: () => FieldDetailPannel.show(context, fieldData), rightIcon: svg("editor/details", color: theme.iconColor), text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index 581a3934e7..0a057b5727 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -50,15 +50,15 @@ class DateTypeOptionWidget extends TypeOptionWidget { listener: (context, state) => dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()), builder: (context, state) { return Column(children: [ - _dateFormatButton(context), - _timeFormatButton(context), + _dateFormatButton(context, state.typeOption.dateFormat), + _timeFormatButton(context, state.typeOption.timeFormat), ]); }, ), ); } - Widget _dateFormatButton(BuildContext context) { + Widget _dateFormatButton(BuildContext context, DateFormat dataFormat) { final theme = context.watch(); return SizedBox( height: GridSize.typeOptionItemHeight, @@ -67,9 +67,12 @@ class DateTypeOptionWidget extends TypeOptionWidget { padding: GridSize.typeOptionContentInsets, hoverColor: theme.hover, onTap: () { - final list = DateFormatList(onSelected: (format) { - context.read().add(DateTypeOptionEvent.didSelectDateFormat(format)); - }); + final list = DateFormatList( + selectedFormat: dataFormat, + onSelected: (format) { + context.read().add(DateTypeOptionEvent.didSelectDateFormat(format)); + }, + ); overlayDelegate.showOverlay(context, list); }, rightIcon: svg("grid/more", color: theme.iconColor), @@ -77,7 +80,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { ); } - Widget _timeFormatButton(BuildContext context) { + Widget _timeFormatButton(BuildContext context, TimeFormat timeFormat) { final theme = context.watch(); return SizedBox( height: GridSize.typeOptionItemHeight, @@ -86,9 +89,11 @@ class DateTypeOptionWidget extends TypeOptionWidget { padding: GridSize.typeOptionContentInsets, hoverColor: theme.hover, onTap: () { - final list = TimeFormatList(onSelected: (format) { - context.read().add(DateTypeOptionEvent.didSelectTimeFormat(format)); - }); + final list = TimeFormatList( + selectedFormat: timeFormat, + onSelected: (format) { + context.read().add(DateTypeOptionEvent.didSelectTimeFormat(format)); + }); overlayDelegate.showOverlay(context, list); }, rightIcon: svg("grid/more", color: theme.iconColor), @@ -98,8 +103,9 @@ class DateTypeOptionWidget extends TypeOptionWidget { } class DateFormatList extends StatelessWidget { + final DateFormat selectedFormat; final Function(DateFormat format) onSelected; - const DateFormatList({required this.onSelected, Key? key}) : super(key: key); + const DateFormatList({required this.selectedFormat, required this.onSelected, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -109,7 +115,8 @@ class DateFormatList extends StatelessWidget { onSelected: (format) { onSelected(format); FlowyOverlay.of(context).remove(identifier()); - }); + }, + isSelected: selectedFormat == format); }).toList(); return SizedBox( @@ -134,18 +141,30 @@ class DateFormatList extends StatelessWidget { } class DateFormatItem extends StatelessWidget { + final bool isSelected; final DateFormat dateFormat; final Function(DateFormat format) onSelected; - const DateFormatItem({required this.dateFormat, required this.onSelected, Key? key}) : super(key: key); + const DateFormatItem({ + required this.dateFormat, + required this.onSelected, + required this.isSelected, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); + Widget? checkmark; + if (isSelected) { + checkmark = svg("grid/checkmark"); + } + return SizedBox( height: GridSize.typeOptionItemHeight, child: FlowyButton( text: FlowyText.medium(dateFormat.title(), fontSize: 12), hoverColor: theme.hover, + rightIcon: checkmark, onTap: () => onSelected(dateFormat), ), ); @@ -170,13 +189,19 @@ extension DateFormatExtension on DateFormat { } class TimeFormatList extends StatelessWidget { + final TimeFormat selectedFormat; final Function(TimeFormat format) onSelected; - const TimeFormatList({required this.onSelected, Key? key}) : super(key: key); + const TimeFormatList({ + required this.selectedFormat, + required this.onSelected, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { final formatItems = TimeFormat.values.map((format) { return TimeFormatItem( + isSelected: format == selectedFormat, timeFormat: format, onSelected: (format) { onSelected(format); @@ -207,17 +232,29 @@ class TimeFormatList extends StatelessWidget { class TimeFormatItem extends StatelessWidget { final TimeFormat timeFormat; + final bool isSelected; final Function(TimeFormat format) onSelected; - const TimeFormatItem({required this.timeFormat, required this.onSelected, Key? key}) : super(key: key); + const TimeFormatItem({ + required this.timeFormat, + required this.onSelected, + required this.isSelected, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); + Widget? checkmark; + if (isSelected) { + checkmark = svg("grid/checkmark"); + } + return SizedBox( height: GridSize.typeOptionItemHeight, child: FlowyButton( text: FlowyText.medium(timeFormat.title(), fontSize: 12), hoverColor: theme.hover, + rightIcon: checkmark, onTap: () => onSelected(timeFormat), ), ); From 37491688619436141c54e33e4f77559d72d7f7d7 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 31 Mar 2022 22:51:46 +0800 Subject: [PATCH 079/179] fix: fix some bugs --- .../app_flowy/assets/translations/en.json | 3 +- .../app_flowy/lib/startup/deps_resolver.dart | 13 +- .../grid/field/create_field_bloc.dart | 98 -------- .../grid/field/edit_field_bloc.dart | 108 +++++---- .../application/grid/field/field_service.dart | 40 +++- .../grid/field/grid_field_bloc.dart | 80 +++++++ .../grid/field/switch_field_type_bloc.dart | 28 +-- .../workspace/application/grid/prelude.dart | 2 +- .../{field_type_list.dart => field_list.dart} | 0 .../widgets/header/field_operation_list.dart | 8 +- ...tyep_switcher.dart => field_switcher.dart} | 28 +-- .../header/grid_field_action_sheet.dart | 103 +++++++++ ...eld_pannel.dart => grid_field_editor.dart} | 52 +++-- .../grid/src/widgets/header/grid_header.dart | 8 +- .../src/widgets/header/grid_header_cell.dart | 10 +- .../src/widgets/header/type_option/date.dart | 2 +- .../header/type_option/multi_select.dart | 2 +- .../widgets/header/type_option/number.dart | 2 +- .../header/type_option/option_pannel.dart | 2 +- .../header/type_option/single_select.dart | 2 +- .../lib/src/flowy_overlay/flowy_overlay.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 8 +- .../flowy-grid-data-model/grid.pb.dart | 63 +++-- .../flowy-grid-data-model/grid.pbjson.dart | 16 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 25 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- .../src/protobuf/model/event_map.rs | 16 +- .../src/protobuf/proto/event_map.proto | 2 +- .../flowy-grid/src/services/grid_editor.rs | 53 +++-- .../src/entities/grid.rs | 7 +- .../src/protobuf/model/grid.rs | 217 ++++++++++++------ .../src/protobuf/proto/grid.proto | 5 +- .../src/client_grid/grid_meta_pad.rs | 2 +- 35 files changed, 666 insertions(+), 355 deletions(-) delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{field_type_list.dart => field_list.dart} (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{field_tyep_switcher.dart => field_switcher.dart} (88%) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{create_field_pannel.dart => grid_field_editor.dart} (58%) diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 4bb37ea078..b9ab426fbd 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -166,7 +166,8 @@ "timeFormatTwentyFourHour": "24 hour", "addSelectOption": "Add an option", "optionTitle": "Options", - "addOption": "Add option" + "addOption": "Add option", + "editProperty": "Edit property" }, "selectOption": { "purpleColor": "Purple", diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 4cb0fda104..1bb46f913f 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -165,16 +165,17 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (data, _) => EditFieldBloc( + getIt.registerFactoryParam( + (data, _) => GridFieldBloc( field: data.field, service: FieldService(gridId: data.gridId), ), ); - getIt.registerFactoryParam( - (gridId, _) => CreateFieldBloc( + getIt.registerFactoryParam( + (gridId, fieldLoader) => FieldEditorBloc( service: FieldService(gridId: gridId), + fieldLoader: fieldLoader, ), ); @@ -213,8 +214,8 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (context, _) => FieldTypeSwitchBloc(context), + getIt.registerFactoryParam( + (context, _) => FieldSwitchBloc(context), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart deleted file mode 100644 index 6a5a276214..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/field/create_field_bloc.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'dart:typed_data'; - -import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'field_service.dart'; -import 'package:dartz/dartz.dart'; - -part 'create_field_bloc.freezed.dart'; - -class CreateFieldBloc extends Bloc { - final FieldService service; - - CreateFieldBloc({required this.service}) : super(CreateFieldState.initial(service.gridId)) { - on( - (event, emit) async { - await event.map( - initial: (_InitialField value) async { - await _getEditFieldContext(emit); - }, - updateName: (_UpdateName value) { - emit(state.copyWith(fieldName: value.name)); - }, - switchField: (_SwitchField value) { - emit(state.copyWith(field: Some(value.field), typeOptionData: value.typeOptionData)); - }, - done: (_Done value) async { - await _saveField(emit); - }, - ); - }, - ); - } - - @override - Future close() async { - return super.close(); - } - - Future _saveField(Emitter emit) async { - await state.field.fold( - () async => null, - (field) async { - field.name = state.fieldName; - - final result = await service.createField( - field: field, - typeOptionData: state.typeOptionData, - ); - result.fold((l) => null, (r) => null); - }, - ); - } - - Future _getEditFieldContext(Emitter emit) async { - final result = await service.getEditFieldContext(FieldType.RichText); - result.fold( - (editContext) { - emit(state.copyWith( - field: Some(editContext.gridField), - typeOptionData: editContext.typeOptionData, - fieldName: editContext.gridField.name, - )); - }, - (err) => Log.error(err), - ); - } -} - -@freezed -class CreateFieldEvent with _$CreateFieldEvent { - const factory CreateFieldEvent.initial() = _InitialField; - const factory CreateFieldEvent.updateName(String name) = _UpdateName; - const factory CreateFieldEvent.switchField(Field field, Uint8List typeOptionData) = _SwitchField; - const factory CreateFieldEvent.done() = _Done; -} - -@freezed -class CreateFieldState with _$CreateFieldState { - const factory CreateFieldState({ - required String fieldName, - required String gridId, - required String errorText, - required Option field, - required List typeOptionData, - }) = _CreateFieldState; - - factory CreateFieldState.initial(String gridId) => CreateFieldState( - gridId: gridId, - fieldName: '', - field: none(), - errorText: '', - typeOptionData: List.empty(), - ); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart index 525d5232d7..749cde3420 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart @@ -1,50 +1,38 @@ +import 'dart:typed_data'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'field_service.dart'; +import 'package:dartz/dartz.dart'; part 'edit_field_bloc.freezed.dart'; -class EditFieldBloc extends Bloc { +class FieldEditorBloc extends Bloc { final FieldService service; + final FieldContextLoader _loader; - EditFieldBloc({required Field field, required this.service}) - : super(EditFieldState.initial(EditFieldContext.create()..gridField = field)) { - on( + FieldEditorBloc({ + required this.service, + required FieldContextLoader fieldLoader, + }) : _loader = fieldLoader, + super(FieldEditorState.initial(service.gridId)) { + on( (event, emit) async { await event.map( - initial: (_InitialField value) {}, - updateFieldName: (_UpdateFieldName value) async { - final result = await service.updateField(fieldId: field.id, name: value.name); - result.fold( - (l) => null, - (err) => Log.error(err), - ); + initial: (_InitialField value) async { + await _getEditFieldContext(emit); }, - hideField: (_HideField value) async { - final result = await service.updateField(fieldId: field.id, visibility: false); - result.fold( - (l) => null, - (err) => Log.error(err), - ); + updateName: (_UpdateName value) { + emit(state.copyWith(fieldName: value.name)); }, - deleteField: (_DeleteField value) async { - final result = await service.deleteField(fieldId: field.id); - result.fold( - (l) => null, - (err) => Log.error(err), - ); + switchField: (_SwitchField value) { + emit(state.copyWith(field: Some(value.field), typeOptionData: value.typeOptionData)); }, - duplicateField: (_DuplicateField value) async { - final result = await service.duplicateField(fieldId: field.id); - result.fold( - (l) => null, - (err) => Log.error(err), - ); + done: (_Done value) async { + await _saveField(emit); }, - saveField: (_SaveField value) {}, ); }, ); @@ -54,29 +42,59 @@ class EditFieldBloc extends Bloc { Future close() async { return super.close(); } + + Future _saveField(Emitter emit) async { + await state.field.fold( + () async => null, + (field) async { + field.name = state.fieldName; + final result = await service.createField( + field: field, + typeOptionData: state.typeOptionData, + ); + result.fold((l) => null, (r) => null); + }, + ); + } + + Future _getEditFieldContext(Emitter emit) async { + final result = await _loader.load(); + result.fold( + (editContext) { + emit(state.copyWith( + field: Some(editContext.gridField), + typeOptionData: editContext.typeOptionData, + fieldName: editContext.gridField.name, + )); + }, + (err) => Log.error(err), + ); + } } @freezed -class EditFieldEvent with _$EditFieldEvent { - const factory EditFieldEvent.initial() = _InitialField; - const factory EditFieldEvent.updateFieldName(String name) = _UpdateFieldName; - const factory EditFieldEvent.hideField() = _HideField; - const factory EditFieldEvent.duplicateField() = _DuplicateField; - const factory EditFieldEvent.deleteField() = _DeleteField; - const factory EditFieldEvent.saveField() = _SaveField; +class FieldEditorEvent with _$FieldEditorEvent { + const factory FieldEditorEvent.initial() = _InitialField; + const factory FieldEditorEvent.updateName(String name) = _UpdateName; + const factory FieldEditorEvent.switchField(Field field, Uint8List typeOptionData) = _SwitchField; + const factory FieldEditorEvent.done() = _Done; } @freezed -class EditFieldState with _$EditFieldState { - const factory EditFieldState({ - required EditFieldContext editContext, - required String errorText, +class FieldEditorState with _$FieldEditorState { + const factory FieldEditorState({ required String fieldName, - }) = _EditFieldState; + required String gridId, + required String errorText, + required Option field, + required List typeOptionData, + }) = _FieldEditorState; - factory EditFieldState.initial(EditFieldContext editContext) => EditFieldState( - editContext: editContext, + factory FieldEditorState.initial(String gridId) => FieldEditorState( + gridId: gridId, + fieldName: '', + field: none(), errorText: '', - fieldName: editContext.gridField.name, + typeOptionData: List.empty(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 24644f0fae..b38d9ffba1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -11,11 +11,11 @@ class FieldService { FieldService({required this.gridId}); Future> getEditFieldContext(FieldType fieldType) { - final payload = CreateEditFieldContextParams.create() + final payload = GetEditFieldContextParams.create() ..gridId = gridId ..fieldType = fieldType; - return GridEventCreateEditFieldContext(payload).send(); + return GridEventGetEditFieldContext(payload).send(); } Future> updateField({ @@ -108,3 +108,39 @@ class GridFieldData extends Equatable { @override List get props => [field.id]; } + +abstract class FieldContextLoader { + Future> load(); +} + +class NewFieldContextLoader extends FieldContextLoader { + final String gridId; + NewFieldContextLoader({ + required this.gridId, + }); + + @override + Future> load() { + final payload = GetEditFieldContextParams.create() + ..gridId = gridId + ..fieldType = FieldType.RichText; + + return GridEventGetEditFieldContext(payload).send(); + } +} + +class FieldContextLoaderAdaptor extends FieldContextLoader { + final GridFieldData data; + + FieldContextLoaderAdaptor(this.data); + + @override + Future> load() { + final payload = GetEditFieldContextParams.create() + ..gridId = data.gridId + ..fieldId = data.field.id + ..fieldType = data.field.fieldType; + + return GridEventGetEditFieldContext(payload).send(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart new file mode 100644 index 0000000000..f3ec3b4cbe --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart @@ -0,0 +1,80 @@ +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'grid_field_bloc.freezed.dart'; + +class GridFieldBloc extends Bloc { + final FieldService service; + + GridFieldBloc({required Field field, required this.service}) + : super(GridFieldState.initial(EditFieldContext.create()..gridField = field)) { + on( + (event, emit) async { + await event.map( + updateFieldName: (_UpdateFieldName value) async { + final result = await service.updateField(fieldId: field.id, name: value.name); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + hideField: (_HideField value) async { + final result = await service.updateField(fieldId: field.id, visibility: false); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + deleteField: (_DeleteField value) async { + final result = await service.deleteField(fieldId: field.id); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + duplicateField: (_DuplicateField value) async { + final result = await service.duplicateField(fieldId: field.id); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + saveField: (_SaveField value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class GridFieldEvent with _$GridFieldEvent { + const factory GridFieldEvent.updateFieldName(String name) = _UpdateFieldName; + const factory GridFieldEvent.hideField() = _HideField; + const factory GridFieldEvent.duplicateField() = _DuplicateField; + const factory GridFieldEvent.deleteField() = _DeleteField; + const factory GridFieldEvent.saveField() = _SaveField; +} + +@freezed +class GridFieldState with _$GridFieldState { + const factory GridFieldState({ + required EditFieldContext editContext, + required String errorText, + required String fieldName, + }) = _GridFieldState; + + factory GridFieldState.initial(EditFieldContext editContext) => GridFieldState( + editContext: editContext, + errorText: '', + fieldName: editContext.gridField.name, + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart index ba8371c3a3..1bb2bb18ce 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart @@ -9,9 +9,9 @@ import 'field_service.dart'; part 'switch_field_type_bloc.freezed.dart'; -class FieldTypeSwitchBloc extends Bloc { - FieldTypeSwitchBloc(SwitchFieldContext editContext) : super(FieldTypeSwitchState.initial(editContext)) { - on( +class FieldSwitchBloc extends Bloc { + FieldSwitchBloc(SwitchFieldContext editContext) : super(FieldSwitchState.initial(editContext)) { + on( (event, emit) async { await event.map( toFieldType: (_ToFieldType value) async { @@ -19,12 +19,8 @@ class FieldTypeSwitchBloc extends Bloc Log.error(err), ); @@ -44,20 +40,20 @@ class FieldTypeSwitchBloc extends Bloc FieldTypeSwitchState( + factory FieldSwitchState.initial(SwitchFieldContext switchContext) => FieldSwitchState( gridId: switchContext.gridId, field: switchContext.field, typeOptionData: Uint8List.fromList(switchContext.typeOptionData), diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index e1d3020ae0..8b13a4f34d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -7,8 +7,8 @@ export 'data.dart'; // Field export 'field/field_service.dart'; export 'field/grid_header_bloc.dart'; +export 'field/grid_field_bloc.dart'; export 'field/edit_field_bloc.dart'; -export 'field/create_field_bloc.dart'; export 'field/switch_field_type_bloc.dart'; // Field Type Option diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart index a4ccc94a94..956060039d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/field/edit_field_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/grid_field_bloc.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; @@ -86,13 +86,13 @@ extension _FieldActionExtension on FieldAction { void run(BuildContext context) { switch (this) { case FieldAction.hide: - context.read().add(const EditFieldEvent.hideField()); + context.read().add(const GridFieldEvent.hideField()); break; case FieldAction.duplicate: - context.read().add(const EditFieldEvent.duplicateField()); + context.read().add(const GridFieldEvent.duplicateField()); break; case FieldAction.delete: - context.read().add(const EditFieldEvent.deleteField()); + context.read().add(const GridFieldEvent.deleteField()); break; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart similarity index 88% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index e8eb5caee2..5f11d750d8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -15,39 +15,41 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart'; import 'type_option/multi_select.dart'; import 'type_option/number.dart'; import 'type_option/single_select.dart'; -typedef SelectFieldCallback = void Function(Field, Uint8List); +typedef UpdateFieldCallback = void Function(Field, Uint8List); -class FieldTypeSwitcher extends StatefulWidget { +class FieldSwitcher extends StatefulWidget { final SwitchFieldContext switchContext; - final SelectFieldCallback onSelected; + final UpdateFieldCallback onUpdated; - const FieldTypeSwitcher({ + const FieldSwitcher({ required this.switchContext, - required this.onSelected, + required this.onUpdated, Key? key, }) : super(key: key); @override - State createState() => _FieldTypeSwitcherState(); + State createState() => _FieldSwitcherState(); } -class _FieldTypeSwitcherState extends State { +class _FieldSwitcherState extends State { String? currentOverlayIdentifier; @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: widget.switchContext), - child: BlocBuilder( + create: (context) => getIt(param1: widget.switchContext), + child: BlocConsumer( + listener: (context, state) { + widget.onUpdated(state.field, state.typeOptionData); + }, builder: (context, state) { List children = [_switchFieldTypeButton(context, state.field)]; - final typeOptionWidget = _typeOptionWidget( context: context, field: state.field, @@ -77,7 +79,7 @@ class _FieldTypeSwitcherState extends State { hoverColor: theme.hover, onTap: () { final list = FieldTypeList(onSelectField: (fieldType) { - context.read().add(FieldTypeSwitchEvent.toFieldType(fieldType)); + context.read().add(FieldSwitchEvent.toFieldType(fieldType)); }); _showOverlay(context, list); }, @@ -98,7 +100,7 @@ class _FieldTypeSwitcherState extends State { ); final dataDelegate = TypeOptionDataDelegate(didUpdateTypeOptionData: (data) { - context.read().add(FieldTypeSwitchEvent.didUpdateTypeOptionData(data)); + context.read().add(FieldSwitchEvent.didUpdateTypeOptionData(data)); }); final builder = _makeTypeOptionBuild( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart new file mode 100644 index 0000000000..13f9fbaba5 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart @@ -0,0 +1,103 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'field_operation_list.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; + +class GridFieldActionSheet extends StatelessWidget with FlowyOverlayDelegate { + final GridFieldData fieldData; + final VoidCallback onEdited; + const GridFieldActionSheet({required this.fieldData, required this.onEdited, Key? key}) : super(key: key); + + static void show(BuildContext overlayContext, GridFieldData fieldData, final VoidCallback onEdited) { + final editor = GridFieldActionSheet(fieldData: fieldData, onEdited: onEdited); + FlowyOverlay.of(overlayContext).insertWithAnchor( + widget: OverlayContainer( + child: editor, + constraints: BoxConstraints.loose(const Size(240, 200)), + ), + identifier: editor.identifier(), + anchorContext: overlayContext, + anchorDirection: AnchorDirection.bottomWithLeftAligned, + ); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: fieldData), + child: SingleChildScrollView( + child: Column( + children: [ + _EditFieldButton( + onEdited: () { + FlowyOverlay.of(context).remove(identifier()); + onEdited(); + }, + ), + const VSpace(6), + _FieldOperationList(fieldData, () => FlowyOverlay.of(context).remove(identifier())), + ], + ), + ), + ); + } + + String identifier() { + return toString(); + } + + @override + bool asBarrier() => true; +} + +class _EditFieldButton extends StatelessWidget { + final Function() onEdited; + const _EditFieldButton({required this.onEdited, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocBuilder( + builder: (context, state) { + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12), + hoverColor: theme.hover, + onTap: onEdited, + ), + ); + }, + ); + } +} + +class _FieldOperationList extends StatelessWidget { + final GridFieldData fieldData; + final VoidCallback onDismissed; + const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final actions = FieldAction.values + .map( + (action) => FieldActionItem( + fieldId: fieldData.field.id, + action: action, + onTap: onDismissed, + ), + ) + .toList(); + + return FieldOperationList(actions: actions); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart similarity index 58% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart index a530737e28..085f051699 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/create_field_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/field/create_field_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/edit_field_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/field/switch_field_type_bloc.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; @@ -7,19 +8,24 @@ import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_name_input.dart'; -import 'field_tyep_switcher.dart'; +import 'field_switcher.dart'; -class CreateFieldPannel extends FlowyOverlayDelegate { +class FieldEditor extends FlowyOverlayDelegate { final String gridId; - final CreateFieldBloc _createFieldBloc; - CreateFieldPannel({required this.gridId, Key? key}) : _createFieldBloc = getIt(param1: gridId) { - _createFieldBloc.add(const CreateFieldEvent.initial()); + final FieldEditorBloc _fieldEditorBloc; + final FieldContextLoader? fieldContextLoader; + FieldEditor({ + required this.gridId, + required this.fieldContextLoader, + Key? key, + }) : _fieldEditorBloc = getIt(param1: gridId, param2: fieldContextLoader) { + _fieldEditorBloc.add(const FieldEditorEvent.initial()); } - void show(BuildContext context, String gridId) { + void show(BuildContext context) { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( - child: _CreateFieldPannelWidget(_createFieldBloc), + child: _EditFieldPannelWidget(_fieldEditorBloc), constraints: BoxConstraints.loose(const Size(220, 400)), ), identifier: identifier(), @@ -36,22 +42,22 @@ class CreateFieldPannel extends FlowyOverlayDelegate { @override void didRemove() { - _createFieldBloc.add(const CreateFieldEvent.done()); + _fieldEditorBloc.add(const FieldEditorEvent.done()); } @override bool asBarrier() => true; } -class _CreateFieldPannelWidget extends StatelessWidget { - final CreateFieldBloc createFieldBloc; - const _CreateFieldPannelWidget(this.createFieldBloc, {Key? key}) : super(key: key); +class _EditFieldPannelWidget extends StatelessWidget { + final FieldEditorBloc editorBloc; + const _EditFieldPannelWidget(this.editorBloc, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider.value( - value: createFieldBloc, - child: BlocBuilder( + value: editorBloc, + child: BlocBuilder( builder: (context, state) { return state.field.fold( () => const SizedBox(width: 200), @@ -62,7 +68,7 @@ class _CreateFieldPannelWidget extends StatelessWidget { const VSpace(10), const _FieldNameTextField(), const VSpace(10), - _FieldTypeSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)), + _FieldSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)), ], ), ); @@ -72,16 +78,16 @@ class _CreateFieldPannelWidget extends StatelessWidget { } } -class _FieldTypeSwitcher extends StatelessWidget { +class _FieldSwitcher extends StatelessWidget { final SwitchFieldContext switchContext; - const _FieldTypeSwitcher(this.switchContext, {Key? key}) : super(key: key); + const _FieldSwitcher(this.switchContext, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return FieldTypeSwitcher( + return FieldSwitcher( switchContext: switchContext, - onSelected: (field, typeOptionData) { - context.read().add(CreateFieldEvent.switchField(field, typeOptionData)); + onUpdated: (field, typeOptionData) { + context.read().add(FieldEditorEvent.switchField(field, typeOptionData)); }, ); } @@ -92,14 +98,14 @@ class _FieldNameTextField extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( buildWhen: (previous, current) => previous.fieldName != current.fieldName, builder: (context, state) { return FieldNameTextField( name: state.fieldName, - errorText: context.read().state.errorText, + errorText: context.read().state.errorText, onNameChanged: (newName) { - context.read().add(CreateFieldEvent.updateName(newName)); + context.read().add(FieldEditorEvent.updateName(newName)); }, ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 6e07fec904..6125cf4526 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -9,7 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'create_field_pannel.dart'; +import 'grid_field_editor.dart'; import 'grid_header_cell.dart'; class GridHeaderDelegate extends SliverPersistentHeaderDelegate { @@ -113,10 +113,14 @@ class CreateFieldButton extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); + return FlowyButton( text: const FlowyText.medium('New column', fontSize: 12), hoverColor: theme.hover, - onTap: () => CreateFieldPannel(gridId: gridId).show(context, gridId), + onTap: () => FieldEditor( + gridId: gridId, + fieldContextLoader: NewFieldContextLoader(gridId: gridId), + ).show(context), leftIcon: svg("home/add"), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart index 19869ccffc..4efedbfe6d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart @@ -7,7 +7,8 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'field_detail_pannel.dart'; +import 'grid_field_editor.dart'; +import 'grid_field_action_sheet.dart'; class GridHeaderCell extends StatelessWidget { final GridFieldData fieldData; @@ -18,7 +19,12 @@ class GridHeaderCell extends StatelessWidget { final theme = context.watch(); final button = FlowyButton( hoverColor: theme.hover, - onTap: () => FieldDetailPannel.show(context, fieldData), + onTap: () => GridFieldActionSheet.show(context, fieldData, () { + FieldEditor( + gridId: fieldData.gridId, + fieldContextLoader: FieldContextLoaderAdaptor(fieldData), + ).show(context); + }), rightIcon: svg("editor/details", color: theme.iconColor), text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index 0a057b5727..5057d5caee 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -1,7 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/date_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; import 'package:easy_localization/easy_localization.dart' hide DateFormat; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flowy_infra/image.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 23881e9310..99728aeffb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index 97dffd17e1..bbff9dd5ad 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -1,7 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/number_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart index 2c4a1b5e4a..b4039bbce1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart index 76573ef945..ecc0dfc80a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_bloc.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 99d86d22bb..0290cf18b3 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -74,7 +74,7 @@ TransitionBuilder overlayManagerBuilder() { abstract class FlowyOverlayDelegate { bool asBarrier() => false; - void didRemove(); + void didRemove() => {}; } class FlowyOverlay extends StatefulWidget { 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 04098b288e..5f34777079 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 @@ -120,13 +120,13 @@ class GridEventDuplicateField { } } -class GridEventCreateEditFieldContext { - CreateEditFieldContextParams request; - GridEventCreateEditFieldContext(this.request); +class GridEventGetEditFieldContext { + GetEditFieldContextParams request; + GridEventGetEditFieldContext(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.CreateEditFieldContext.toString() + ..event = GridEvent.GetEditFieldContext.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) 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 3dafd193b3..cd3c552036 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 @@ -374,47 +374,65 @@ class FieldOrder extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); } -class CreateEditFieldContextParams extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateEditFieldContextParams', createEmptyInstance: create) +enum GetEditFieldContextParams_OneOfFieldId { + fieldId, + notSet +} + +class GetEditFieldContextParams extends $pb.GeneratedMessage { + static const $core.Map<$core.int, GetEditFieldContextParams_OneOfFieldId> _GetEditFieldContextParams_OneOfFieldIdByTag = { + 2 : GetEditFieldContextParams_OneOfFieldId.fieldId, + 0 : GetEditFieldContextParams_OneOfFieldId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetEditFieldContextParams', createEmptyInstance: create) + ..oo(0, [2]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..e<$0.FieldType>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..e<$0.FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) ..hasRequiredFields = false ; - CreateEditFieldContextParams._() : super(); - factory CreateEditFieldContextParams({ + GetEditFieldContextParams._() : super(); + factory GetEditFieldContextParams({ $core.String? gridId, + $core.String? fieldId, $0.FieldType? fieldType, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } + if (fieldId != null) { + _result.fieldId = fieldId; + } if (fieldType != null) { _result.fieldType = fieldType; } return _result; } - factory CreateEditFieldContextParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CreateEditFieldContextParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GetEditFieldContextParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GetEditFieldContextParams.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') - CreateEditFieldContextParams clone() => CreateEditFieldContextParams()..mergeFromMessage(this); + GetEditFieldContextParams clone() => GetEditFieldContextParams()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - CreateEditFieldContextParams copyWith(void Function(CreateEditFieldContextParams) updates) => super.copyWith((message) => updates(message as CreateEditFieldContextParams)) as CreateEditFieldContextParams; // ignore: deprecated_member_use + GetEditFieldContextParams copyWith(void Function(GetEditFieldContextParams) updates) => super.copyWith((message) => updates(message as GetEditFieldContextParams)) as GetEditFieldContextParams; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static CreateEditFieldContextParams create() => CreateEditFieldContextParams._(); - CreateEditFieldContextParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GetEditFieldContextParams create() => GetEditFieldContextParams._(); + GetEditFieldContextParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static CreateEditFieldContextParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CreateEditFieldContextParams? _defaultInstance; + static GetEditFieldContextParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GetEditFieldContextParams? _defaultInstance; + + GetEditFieldContextParams_OneOfFieldId whichOneOfFieldId() => _GetEditFieldContextParams_OneOfFieldIdByTag[$_whichOneof(0)]!; + void clearOneOfFieldId() => clearField($_whichOneof(0)); @$pb.TagNumber(1) $core.String get gridId => $_getSZ(0); @@ -426,13 +444,22 @@ class CreateEditFieldContextParams extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $0.FieldType get fieldType => $_getN(1); + $core.String get fieldId => $_getSZ(1); @$pb.TagNumber(2) - set fieldType($0.FieldType v) { setField(2, v); } + set fieldId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasFieldType() => $_has(1); + $core.bool hasFieldId() => $_has(1); @$pb.TagNumber(2) - void clearFieldType() => clearField(2); + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $0.FieldType get fieldType => $_getN(2); + @$pb.TagNumber(3) + set fieldType($0.FieldType v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasFieldType() => $_has(2); + @$pb.TagNumber(3) + void clearFieldType() => clearField(3); } class EditFieldContext 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 3b7c58924e..713f10794c 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 @@ -68,17 +68,21 @@ const FieldOrder$json = const { /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); -@$core.Deprecated('Use createEditFieldContextParamsDescriptor instead') -const CreateEditFieldContextParams$json = const { - '1': 'CreateEditFieldContextParams', +@$core.Deprecated('Use getEditFieldContextParamsDescriptor instead') +const GetEditFieldContextParams$json = const { + '1': 'GetEditFieldContextParams', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'field_type', '3': 2, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'fieldId'}, + const {'1': 'field_type', '3': 3, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + ], + '8': const [ + const {'1': 'one_of_field_id'}, ], }; -/// Descriptor for `CreateEditFieldContextParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createEditFieldContextParamsDescriptor = $convert.base64Decode('ChxDcmVhdGVFZGl0RmllbGRDb250ZXh0UGFyYW1zEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIpCgpmaWVsZF90eXBlGAIgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGU='); +/// Descriptor for `GetEditFieldContextParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List getEditFieldContextParamsDescriptor = $convert.base64Decode('ChlHZXRFZGl0RmllbGRDb250ZXh0UGFyYW1zEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIbCghmaWVsZF9pZBgCIAEoCUgAUgdmaWVsZElkEikKCmZpZWxkX3R5cGUYAyABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZUIRCg9vbmVfb2ZfZmllbGRfaWQ='); @$core.Deprecated('Use editFieldContextDescriptor instead') const EditFieldContext$json = const { '1': 'EditFieldContext', 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 25319128d8..38b2bcf764 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 @@ -17,7 +17,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField'); static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); - static const GridEvent CreateEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext'); + static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext'); static const GridEvent CreateSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateSelectOption'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); @@ -31,7 +31,7 @@ class GridEvent extends $pb.ProtobufEnum { CreateField, DeleteField, DuplicateField, - CreateEditFieldContext, + GetEditFieldContext, CreateSelectOption, CreateRow, GetRow, 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 747a591a02..fb883500d5 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 @@ -19,7 +19,7 @@ const GridEvent$json = const { const {'1': 'CreateField', '2': 12}, const {'1': 'DeleteField', '2': 13}, const {'1': 'DuplicateField', '2': 15}, - const {'1': 'CreateEditFieldContext', '2': 16}, + const {'1': 'GetEditFieldContext', '2': 16}, const {'1': 'CreateSelectOption', '2': 30}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, @@ -28,4 +28,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIaChZDcmVhdGVFZGl0RmllbGRDb250ZXh0EBASFgoSQ3JlYXRlU2VsZWN0T3B0aW9uEB4SDQoJQ3JlYXRlUm93EDISCgoGR2V0Um93EDMSDgoKVXBkYXRlQ2VsbBBG'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIXChNHZXRFZGl0RmllbGRDb250ZXh0EBASFgoSQ3JlYXRlU2VsZWN0T3B0aW9uEB4SDQoJQ3JlYXRlUm93EDISCgoGR2V0Um93EDMSDgoKVXBkYXRlQ2VsbBBG'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index d29c2aec48..5ae05c4838 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,6 +1,7 @@ use crate::manager::GridManager; use crate::services::field::{type_option_data_from_str, SelectOption}; -use flowy_error::FlowyError; +use crate::services::grid_editor::ClientGridEditor; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -97,13 +98,14 @@ pub(crate) async fn create_select_option_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn create_edit_field_context_handler( - data: Data, +pub(crate) async fn edit_edit_field_context_handler( + data: Data, manager: AppData>, ) -> DataResult { - let params: CreateEditFieldContextParams = data.into_inner(); + let params: GetEditFieldContextParams = data.into_inner(); let editor = manager.get_grid_editor(¶ms.grid_id)?; - let field_meta = editor.default_field_meta(¶ms.field_type).await?; + + let mut field_meta = get_or_create_field_meta(¶ms, editor).await?; let type_option_data = type_option_data_from_str(&field_meta.type_option_json, &field_meta.field_type); let field: Field = field_meta.into(); let edit_context = EditFieldContext { @@ -114,6 +116,19 @@ pub(crate) async fn create_edit_field_context_handler( data_result(edit_context) } +async fn get_or_create_field_meta( + params: &GetEditFieldContextParams, + editor: Arc, +) -> FlowyResult { + if params.field_id.is_some() { + if let Some(field_meta) = editor.get_field(params.field_id.as_ref().unwrap()).await? { + return Ok(field_meta); + } + } + + editor.default_field_meta(¶ms.field_type).await +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_row_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 966423c7c7..ffc30cf7e1 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -15,7 +15,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::CreateField, create_field_handler) .event(GridEvent::DeleteField, delete_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) - .event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler) + .event(GridEvent::GetEditFieldContext, edit_edit_field_context_handler) .event(GridEvent::CreateSelectOption, create_select_option_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) @@ -48,8 +48,8 @@ pub enum GridEvent { #[event(input = "FieldIdentifierPayload")] DuplicateField = 15, - #[event(input = "CreateEditFieldContextParams", output = "EditFieldContext")] - CreateEditFieldContext = 16, + #[event(input = "GetEditFieldContextParams", output = "EditFieldContext")] + GetEditFieldContext = 16, #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] CreateSelectOption = 30, 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 2eab7357c5..62f0995df0 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 @@ -32,7 +32,7 @@ pub enum GridEvent { CreateField = 12, DeleteField = 13, DuplicateField = 15, - CreateEditFieldContext = 16, + GetEditFieldContext = 16, CreateSelectOption = 30, CreateRow = 50, GetRow = 51, @@ -53,7 +53,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 12 => ::std::option::Option::Some(GridEvent::CreateField), 13 => ::std::option::Option::Some(GridEvent::DeleteField), 15 => ::std::option::Option::Some(GridEvent::DuplicateField), - 16 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext), + 16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext), 30 => ::std::option::Option::Some(GridEvent::CreateSelectOption), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), @@ -71,7 +71,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::CreateField, GridEvent::DeleteField, GridEvent::DuplicateField, - GridEvent::CreateEditFieldContext, + GridEvent::GetEditFieldContext, GridEvent::CreateSelectOption, GridEvent::CreateRow, GridEvent::GetRow, @@ -104,13 +104,13 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xe4\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xe1\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ - leteField\x10\r\x12\x12\n\x0eDuplicateField\x10\x0f\x12\x1a\n\x16CreateE\ - ditFieldContext\x10\x10\x12\x16\n\x12CreateSelectOption\x10\x1e\x12\r\n\ - \tCreateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10Fb\x06p\ - roto3\ + leteField\x10\r\x12\x12\n\x0eDuplicateField\x10\x0f\x12\x17\n\x13GetEdit\ + FieldContext\x10\x10\x12\x16\n\x12CreateSelectOption\x10\x1e\x12\r\n\tCr\ + eateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10Fb\x06proto\ + 3\ "; 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 ebc7ae6782..b977992b96 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 @@ -8,7 +8,7 @@ enum GridEvent { CreateField = 12; DeleteField = 13; DuplicateField = 15; - CreateEditFieldContext = 16; + GetEditFieldContext = 16; CreateSelectOption = 30; CreateRow = 50; GetRow = 51; 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 7ff089ff9b..295353c8d5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -53,24 +53,40 @@ impl ClientGridEditor { field, type_option_data, start_field_id, - .. + grid_id, } = params; - let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); - - let field_meta = FieldMeta { - id: field.id, - name: field.name, - desc: field.desc, - field_type: field.field_type, - frozen: field.frozen, - visibility: field.visibility, - width: field.width, - type_option_json, - }; - let _ = self - .modify(|grid| Ok(grid.create_field(field_meta, start_field_id)?)) + .modify(|grid| { + if grid.contain_field(&field.id) { + let changeset = FieldChangesetParams { + field_id: field.id, + grid_id, + name: Some(field.name), + desc: Some(field.desc), + field_type: Some(field.field_type), + frozen: Some(field.frozen), + visibility: Some(field.visibility), + width: Some(field.width), + type_option_data: Some(type_option_data), + }; + + Ok(grid.update_field(changeset)?) + } else { + let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); + let field_meta = FieldMeta { + id: field.id, + name: field.name, + desc: field.desc, + field_type: field.field_type, + frozen: field.frozen, + visibility: field.visibility, + width: field.width, + type_option_json, + }; + Ok(grid.create_field(field_meta, start_field_id)?) + } + }) .await?; let _ = self.notify_did_update_fields().await?; Ok(()) @@ -116,6 +132,13 @@ impl ClientGridEditor { Ok(()) } + pub async fn get_field(&self, field_id: &str) -> FlowyResult> { + match self.pad.read().await.get_field(field_id) { + None => Ok(None), + Some(field_meta) => Ok(Some(field_meta.clone())), + } + } + pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; 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 a85b8d382a..1b88e52ef7 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -101,11 +101,14 @@ impl std::convert::From<&FieldMeta> for FieldOrder { } #[derive(Debug, Default, ProtoBuf)] -pub struct CreateEditFieldContextParams { +pub struct GetEditFieldContextParams { #[pb(index = 1)] pub grid_id: String, - #[pb(index = 2)] + #[pb(index = 2, one_of)] + pub field_id: Option, + + #[pb(index = 3)] pub field_type: FieldType, } 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 d55c5dac10..6fdc3205e1 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 @@ -1221,23 +1221,30 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { } #[derive(PartialEq,Clone,Default)] -pub struct CreateEditFieldContextParams { +pub struct GetEditFieldContextParams { // message fields pub grid_id: ::std::string::String, pub field_type: super::meta::FieldType, + // message oneof groups + pub one_of_field_id: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a CreateEditFieldContextParams { - fn default() -> &'a CreateEditFieldContextParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a GetEditFieldContextParams { + fn default() -> &'a GetEditFieldContextParams { + ::default_instance() } } -impl CreateEditFieldContextParams { - pub fn new() -> CreateEditFieldContextParams { +#[derive(Clone,PartialEq,Debug)] +pub enum GetEditFieldContextParams_oneof_one_of_field_id { + field_id(::std::string::String), +} + +impl GetEditFieldContextParams { + pub fn new() -> GetEditFieldContextParams { ::std::default::Default::default() } @@ -1267,7 +1274,56 @@ impl CreateEditFieldContextParams { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // .FieldType field_type = 2; + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + match self.one_of_field_id { + ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref v)) => v, + _ => "", + } + } + pub fn clear_field_id(&mut self) { + self.one_of_field_id = ::std::option::Option::None; + } + + pub fn has_field_id(&self) -> bool { + match self.one_of_field_id { + ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(_)) = self.one_of_field_id { + } else { + self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(::std::string::String::new())); + } + match self.one_of_field_id { + ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + if self.has_field_id() { + match self.one_of_field_id.take() { + ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // .FieldType field_type = 3; pub fn get_field_type(&self) -> super::meta::FieldType { @@ -1283,7 +1339,7 @@ impl CreateEditFieldContextParams { } } -impl ::protobuf::Message for CreateEditFieldContextParams { +impl ::protobuf::Message for GetEditFieldContextParams { fn is_initialized(&self) -> bool { true } @@ -1296,7 +1352,13 @@ impl ::protobuf::Message for CreateEditFieldContextParams { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 2, &mut self.unknown_fields)? + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(is.read_string()?)); + }, + 3 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 3, &mut self.unknown_fields)? }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -1314,7 +1376,14 @@ impl ::protobuf::Message for CreateEditFieldContextParams { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } if self.field_type != super::meta::FieldType::RichText { - my_size += ::protobuf::rt::enum_size(2, self.field_type); + my_size += ::protobuf::rt::enum_size(3, self.field_type); + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_id { + match v { + &GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref v) => { + my_size += ::protobuf::rt::string_size(2, &v); + }, + }; } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1326,7 +1395,14 @@ impl ::protobuf::Message for CreateEditFieldContextParams { os.write_string(1, &self.grid_id)?; } if self.field_type != super::meta::FieldType::RichText { - os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.field_type))?; + os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_id { + match v { + &GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref v) => { + os.write_string(2, v)?; + }, + }; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1358,8 +1434,8 @@ impl ::protobuf::Message for CreateEditFieldContextParams { Self::descriptor_static() } - fn new() -> CreateEditFieldContextParams { - CreateEditFieldContextParams::new() + fn new() -> GetEditFieldContextParams { + GetEditFieldContextParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1368,43 +1444,49 @@ impl ::protobuf::Message for CreateEditFieldContextParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &CreateEditFieldContextParams| { &m.grid_id }, - |m: &mut CreateEditFieldContextParams| { &mut m.grid_id }, + |m: &GetEditFieldContextParams| { &m.grid_id }, + |m: &mut GetEditFieldContextParams| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "field_id", + GetEditFieldContextParams::has_field_id, + GetEditFieldContextParams::get_field_id, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "field_type", - |m: &CreateEditFieldContextParams| { &m.field_type }, - |m: &mut CreateEditFieldContextParams| { &mut m.field_type }, + |m: &GetEditFieldContextParams| { &m.field_type }, + |m: &mut GetEditFieldContextParams| { &mut m.field_type }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CreateEditFieldContextParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GetEditFieldContextParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static CreateEditFieldContextParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CreateEditFieldContextParams::new) + fn default_instance() -> &'static GetEditFieldContextParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GetEditFieldContextParams::new) } } -impl ::protobuf::Clear for CreateEditFieldContextParams { +impl ::protobuf::Clear for GetEditFieldContextParams { fn clear(&mut self) { self.grid_id.clear(); + self.one_of_field_id = ::std::option::Option::None; self.field_type = super::meta::FieldType::RichText; self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for CreateEditFieldContextParams { +impl ::std::fmt::Debug for GetEditFieldContextParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CreateEditFieldContextParams { +impl ::protobuf::reflect::ProtobufValue for GetEditFieldContextParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -5431,48 +5513,49 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"K\n\x15FieldIdentifierParams\ \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\"b\n\x1cCreateEditFieldContextParams\x12\ - \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12)\n\nfield_type\x18\ - \x02\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\ - \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\ - \x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\ - \x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05it\ - ems\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ - RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ - lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ - yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ - \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ - (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ - \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ - \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ - \x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\ - \x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ - 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ - \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ - \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ - R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ - lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ - \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ - idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ - \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ - rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ - \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ - \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ - \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ - ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ - ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ - \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ - ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ - \x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ - \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"<\n\x19CreateSelec\ - tOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionNameb\ - \x06proto3\ + \x18\x01\x20\x01(\tR\x07fieldId\"\x8f\x01\n\x19GetEditFieldContextParams\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_i\ + d\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\ + \x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"|\n\x10EditFiel\ + dContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid\ + _field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option\ + _data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ + \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ + edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ + ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ + t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ + \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ + \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ + \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ + .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ + \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ + items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\ + \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ + \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ + \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ + \x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b\ + 2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\ + \x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\ + \x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01\ + (\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstart\ + RowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\ + \x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ + \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ + \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ + \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ + \x0f.GridBlockOrderR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ + \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ + \"<\n\x19CreateSelectOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\ + \x01(\tR\noptionNameb\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 5c07b98d30..cba28ad711 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 @@ -26,9 +26,10 @@ message FieldIdentifierParams { message FieldOrder { string field_id = 1; } -message CreateEditFieldContextParams { +message GetEditFieldContextParams { string grid_id = 1; - FieldType field_type = 2; + oneof one_of_field_id { string field_id = 2; }; + FieldType field_type = 3; } message EditFieldContext { string grid_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 78c0091b57..d3e407a763 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -45,7 +45,7 @@ impl GridMetaPad { self.modify_grid(|grid| { // Check if the field exists or not if grid.fields.iter().any(|field_meta| field_meta.id == new_field_meta.id) { - tracing::warn!("Duplicate grid field"); + tracing::error!("Duplicate grid field"); return Ok(None); } From 80f82fa5b1a95f71effcf6c2e8afc308e9bae427 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 1 Apr 2022 09:31:10 +0800 Subject: [PATCH 080/179] chore: update field type option data using deserializer --- .../application/grid/field/field_service.dart | 12 +- .../grid/field/switch_field_type_bloc.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 19 +- .../flowy-grid-data-model/grid.pb.dart | 111 ++++- .../flowy-grid-data-model/grid.pbjson.dart | 22 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 2 + .../protobuf/flowy-grid/event_map.pbjson.dart | 3 +- .../rust-lib/flowy-grid/src/event_handler.rs | 19 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 8 +- .../src/protobuf/model/event_map.rs | 13 +- .../src/protobuf/proto/event_map.proto | 1 + .../flowy-grid/src/services/grid_editor.rs | 41 +- .../src/entities/grid.rs | 34 +- .../src/protobuf/model/grid.rs | 391 ++++++++++++++---- .../src/protobuf/proto/grid.proto | 7 +- .../src/client_grid/grid_meta_pad.rs | 12 +- 16 files changed, 558 insertions(+), 139 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index b38d9ffba1..5bb80a0119 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -10,12 +10,13 @@ class FieldService { FieldService({required this.gridId}); - Future> getEditFieldContext(FieldType fieldType) { - final payload = GetEditFieldContextParams.create() + Future> switchToField(String fieldId, FieldType fieldType) { + final payload = EditFieldPayload.create() ..gridId = gridId + ..fieldId = fieldId ..fieldType = fieldType; - return GridEventGetEditFieldContext(payload).send(); + return GridEventSwitchToField(payload).send(); } Future> updateField({ @@ -58,6 +59,7 @@ class FieldService { return GridEventUpdateField(payload).send(); } + // Create the field if it does not exist. Otherwise, update the field. Future> createField({ required Field field, List? typeOptionData, @@ -121,7 +123,7 @@ class NewFieldContextLoader extends FieldContextLoader { @override Future> load() { - final payload = GetEditFieldContextParams.create() + final payload = GetEditFieldContextPayload.create() ..gridId = gridId ..fieldType = FieldType.RichText; @@ -136,7 +138,7 @@ class FieldContextLoaderAdaptor extends FieldContextLoader { @override Future> load() { - final payload = GetEditFieldContextParams.create() + final payload = GetEditFieldContextPayload.create() ..gridId = data.gridId ..fieldId = data.field.id ..fieldType = data.field.fieldType; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart index 1bb2bb18ce..edb0732ddf 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart @@ -16,7 +16,7 @@ class FieldSwitchBloc extends Bloc { await event.map( toFieldType: (_ToFieldType value) async { final fieldService = FieldService(gridId: state.gridId); - final result = await fieldService.getEditFieldContext(value.fieldType); + final result = await fieldService.switchToField(state.field.id, value.fieldType); result.fold( (newEditContext) { final typeOptionData = Uint8List.fromList(newEditContext.typeOptionData); 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 5f34777079..45b33f1004 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 @@ -103,6 +103,23 @@ class GridEventDeleteField { } } +class GridEventSwitchToField { + EditFieldPayload request; + GridEventSwitchToField(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.SwitchToField.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(EditFieldContext.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventDuplicateField { FieldIdentifierPayload request; GridEventDuplicateField(this.request); @@ -121,7 +138,7 @@ class GridEventDuplicateField { } class GridEventGetEditFieldContext { - GetEditFieldContextParams request; + GetEditFieldContextPayload request; GridEventGetEditFieldContext(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 cd3c552036..7fcee422d7 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 @@ -374,17 +374,17 @@ class FieldOrder extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); } -enum GetEditFieldContextParams_OneOfFieldId { +enum GetEditFieldContextPayload_OneOfFieldId { fieldId, notSet } -class GetEditFieldContextParams extends $pb.GeneratedMessage { - static const $core.Map<$core.int, GetEditFieldContextParams_OneOfFieldId> _GetEditFieldContextParams_OneOfFieldIdByTag = { - 2 : GetEditFieldContextParams_OneOfFieldId.fieldId, - 0 : GetEditFieldContextParams_OneOfFieldId.notSet +class GetEditFieldContextPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, GetEditFieldContextPayload_OneOfFieldId> _GetEditFieldContextPayload_OneOfFieldIdByTag = { + 2 : GetEditFieldContextPayload_OneOfFieldId.fieldId, + 0 : GetEditFieldContextPayload_OneOfFieldId.notSet }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetEditFieldContextParams', createEmptyInstance: create) + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetEditFieldContextPayload', createEmptyInstance: create) ..oo(0, [2]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') @@ -392,8 +392,8 @@ class GetEditFieldContextParams extends $pb.GeneratedMessage { ..hasRequiredFields = false ; - GetEditFieldContextParams._() : super(); - factory GetEditFieldContextParams({ + GetEditFieldContextPayload._() : super(); + factory GetEditFieldContextPayload({ $core.String? gridId, $core.String? fieldId, $0.FieldType? fieldType, @@ -410,28 +410,28 @@ class GetEditFieldContextParams extends $pb.GeneratedMessage { } return _result; } - factory GetEditFieldContextParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GetEditFieldContextParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GetEditFieldContextPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GetEditFieldContextPayload.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') - GetEditFieldContextParams clone() => GetEditFieldContextParams()..mergeFromMessage(this); + GetEditFieldContextPayload clone() => GetEditFieldContextPayload()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GetEditFieldContextParams copyWith(void Function(GetEditFieldContextParams) updates) => super.copyWith((message) => updates(message as GetEditFieldContextParams)) as GetEditFieldContextParams; // ignore: deprecated_member_use + GetEditFieldContextPayload copyWith(void Function(GetEditFieldContextPayload) updates) => super.copyWith((message) => updates(message as GetEditFieldContextPayload)) as GetEditFieldContextPayload; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GetEditFieldContextParams create() => GetEditFieldContextParams._(); - GetEditFieldContextParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GetEditFieldContextPayload create() => GetEditFieldContextPayload._(); + GetEditFieldContextPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GetEditFieldContextParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GetEditFieldContextParams? _defaultInstance; + static GetEditFieldContextPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GetEditFieldContextPayload? _defaultInstance; - GetEditFieldContextParams_OneOfFieldId whichOneOfFieldId() => _GetEditFieldContextParams_OneOfFieldIdByTag[$_whichOneof(0)]!; + GetEditFieldContextPayload_OneOfFieldId whichOneOfFieldId() => _GetEditFieldContextPayload_OneOfFieldIdByTag[$_whichOneof(0)]!; void clearOneOfFieldId() => clearField($_whichOneof(0)); @$pb.TagNumber(1) @@ -462,6 +462,81 @@ class GetEditFieldContextParams extends $pb.GeneratedMessage { void clearFieldType() => clearField(3); } +class EditFieldPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'EditFieldPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..e<$0.FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..hasRequiredFields = false + ; + + EditFieldPayload._() : super(); + factory EditFieldPayload({ + $core.String? gridId, + $core.String? fieldId, + $0.FieldType? fieldType, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + return _result; + } + factory EditFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory EditFieldPayload.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') + EditFieldPayload clone() => EditFieldPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + EditFieldPayload copyWith(void Function(EditFieldPayload) updates) => super.copyWith((message) => updates(message as EditFieldPayload)) as EditFieldPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static EditFieldPayload create() => EditFieldPayload._(); + EditFieldPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static EditFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static EditFieldPayload? _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 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) + $0.FieldType get fieldType => $_getN(2); + @$pb.TagNumber(3) + set fieldType($0.FieldType v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasFieldType() => $_has(2); + @$pb.TagNumber(3) + void clearFieldType() => clearField(3); +} + class EditFieldContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'EditFieldContext', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 713f10794c..596c7f6fc1 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 @@ -68,9 +68,9 @@ const FieldOrder$json = const { /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); -@$core.Deprecated('Use getEditFieldContextParamsDescriptor instead') -const GetEditFieldContextParams$json = const { - '1': 'GetEditFieldContextParams', +@$core.Deprecated('Use getEditFieldContextPayloadDescriptor instead') +const GetEditFieldContextPayload$json = const { + '1': 'GetEditFieldContextPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'fieldId'}, @@ -81,8 +81,20 @@ const GetEditFieldContextParams$json = const { ], }; -/// Descriptor for `GetEditFieldContextParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List getEditFieldContextParamsDescriptor = $convert.base64Decode('ChlHZXRFZGl0RmllbGRDb250ZXh0UGFyYW1zEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIbCghmaWVsZF9pZBgCIAEoCUgAUgdmaWVsZElkEikKCmZpZWxkX3R5cGUYAyABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZUIRCg9vbmVfb2ZfZmllbGRfaWQ='); +/// Descriptor for `GetEditFieldContextPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List getEditFieldContextPayloadDescriptor = $convert.base64Decode('ChpHZXRFZGl0RmllbGRDb250ZXh0UGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSGwoIZmllbGRfaWQYAiABKAlIAFIHZmllbGRJZBIpCgpmaWVsZF90eXBlGAMgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGVCEQoPb25lX29mX2ZpZWxkX2lk'); +@$core.Deprecated('Use editFieldPayloadDescriptor instead') +const EditFieldPayload$json = const { + '1': 'EditFieldPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'field_type', '3': 3, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + ], +}; + +/// Descriptor for `EditFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List editFieldPayloadDescriptor = $convert.base64Decode('ChBFZGl0RmllbGRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIpCgpmaWVsZF90eXBlGAMgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGU='); @$core.Deprecated('Use editFieldContextDescriptor instead') const EditFieldContext$json = const { '1': 'EditFieldContext', 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 38b2bcf764..7d69a59524 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 @@ -16,6 +16,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField'); + static const GridEvent SwitchToField = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SwitchToField'); static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext'); static const GridEvent CreateSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateSelectOption'); @@ -30,6 +31,7 @@ class GridEvent extends $pb.ProtobufEnum { UpdateField, CreateField, DeleteField, + SwitchToField, DuplicateField, GetEditFieldContext, CreateSelectOption, 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 fb883500d5..dc5ca350b6 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 @@ -18,6 +18,7 @@ const GridEvent$json = const { const {'1': 'UpdateField', '2': 11}, const {'1': 'CreateField', '2': 12}, const {'1': 'DeleteField', '2': 13}, + const {'1': 'SwitchToField', '2': 14}, const {'1': 'DuplicateField', '2': 15}, const {'1': 'GetEditFieldContext', '2': 16}, const {'1': 'CreateSelectOption', '2': 30}, @@ -28,4 +29,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIXChNHZXRFZGl0RmllbGRDb250ZXh0EBASFgoSQ3JlYXRlU2VsZWN0T3B0aW9uEB4SDQoJQ3JlYXRlUm93EDISCgoGR2V0Um93EDMSDgoKVXBkYXRlQ2VsbBBG'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg4KClVwZGF0ZUNlbGwQRg=='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 5ae05c4838..25f11c3010 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -78,6 +78,17 @@ pub(crate) async fn delete_field_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn switch_to_field_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: EditFieldParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let edit_context = editor.switch_to_field_type(¶ms.field_id, params.field_type).await?; + data_result(edit_context) +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn duplicate_field_handler( data: Data, @@ -98,11 +109,11 @@ pub(crate) async fn create_select_option_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn edit_edit_field_context_handler( - data: Data, +pub(crate) async fn get_field_context_handler( + data: Data, manager: AppData>, ) -> DataResult { - let params: GetEditFieldContextParams = data.into_inner(); + let params = data.into_inner(); let editor = manager.get_grid_editor(¶ms.grid_id)?; let mut field_meta = get_or_create_field_meta(¶ms, editor).await?; @@ -117,7 +128,7 @@ pub(crate) async fn edit_edit_field_context_handler( } async fn get_or_create_field_meta( - params: &GetEditFieldContextParams, + params: &GetEditFieldContextPayload, editor: Arc, ) -> FlowyResult { if params.field_id.is_some() { diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index ffc30cf7e1..5183b8afb7 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -14,8 +14,9 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) .event(GridEvent::DeleteField, delete_field_handler) + .event(GridEvent::SwitchToField, switch_to_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) - .event(GridEvent::GetEditFieldContext, edit_edit_field_context_handler) + .event(GridEvent::GetEditFieldContext, get_field_context_handler) .event(GridEvent::CreateSelectOption, create_select_option_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) @@ -45,10 +46,13 @@ pub enum GridEvent { #[event(input = "FieldIdentifierPayload")] DeleteField = 13, + #[event(input = "EditFieldPayload", output = "EditFieldContext")] + SwitchToField = 14, + #[event(input = "FieldIdentifierPayload")] DuplicateField = 15, - #[event(input = "GetEditFieldContextParams", output = "EditFieldContext")] + #[event(input = "GetEditFieldContextPayload", output = "EditFieldContext")] GetEditFieldContext = 16, #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] 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 62f0995df0..368c4df718 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 @@ -31,6 +31,7 @@ pub enum GridEvent { UpdateField = 11, CreateField = 12, DeleteField = 13, + SwitchToField = 14, DuplicateField = 15, GetEditFieldContext = 16, CreateSelectOption = 30, @@ -52,6 +53,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 11 => ::std::option::Option::Some(GridEvent::UpdateField), 12 => ::std::option::Option::Some(GridEvent::CreateField), 13 => ::std::option::Option::Some(GridEvent::DeleteField), + 14 => ::std::option::Option::Some(GridEvent::SwitchToField), 15 => ::std::option::Option::Some(GridEvent::DuplicateField), 16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext), 30 => ::std::option::Option::Some(GridEvent::CreateSelectOption), @@ -70,6 +72,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::UpdateField, GridEvent::CreateField, GridEvent::DeleteField, + GridEvent::SwitchToField, GridEvent::DuplicateField, GridEvent::GetEditFieldContext, GridEvent::CreateSelectOption, @@ -104,13 +107,13 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xe1\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xf4\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ - leteField\x10\r\x12\x12\n\x0eDuplicateField\x10\x0f\x12\x17\n\x13GetEdit\ - FieldContext\x10\x10\x12\x16\n\x12CreateSelectOption\x10\x1e\x12\r\n\tCr\ - eateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10Fb\x06proto\ - 3\ + leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ + ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x16\n\x12Creat\ + eSelectOption\x10\x1e\x12\r\n\tCreateRow\x102\x12\n\n\x06GetRow\x103\x12\ + \x0e\n\nUpdateCell\x10Fb\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 b977992b96..9d2ea5961f 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 @@ -7,6 +7,7 @@ enum GridEvent { UpdateField = 11; CreateField = 12; DeleteField = 13; + SwitchToField = 14; DuplicateField = 15; GetEditFieldContext = 16; CreateSelectOption = 30; 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 295353c8d5..3b48f244d5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -7,8 +7,9 @@ use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; -use flowy_sync::client_grid::{GridChangeset, GridMetaPad}; +use flowy_sync::client_grid::{GridChangeset, GridMetaPad, TypeOptionDataDeserializer}; use flowy_sync::entities::revision::Revision; +use flowy_sync::errors::CollaborateResult; use flowy_sync::util::make_delta_from_revisions; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; @@ -59,6 +60,7 @@ impl ClientGridEditor { let _ = self .modify(|grid| { if grid.contain_field(&field.id) { + let deserializer = TypeOptionChangesetDeserializer(field.field_type.clone()); let changeset = FieldChangesetParams { field_id: field.id, grid_id, @@ -70,8 +72,7 @@ impl ClientGridEditor { width: Some(field.width), type_option_data: Some(type_option_data), }; - - Ok(grid.update_field(changeset)?) + Ok(grid.update_field(changeset, deserializer)?) } else { let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); let field_meta = FieldMeta { @@ -103,19 +104,12 @@ impl ClientGridEditor { } pub async fn update_field(&self, mut params: FieldChangesetParams) -> FlowyResult<()> { - if let Some(type_option_data) = params.type_option_data { - match self.pad.read().await.get_field(¶ms.field_id) { - None => return Err(ErrorCode::FieldDoesNotExist.into()), - Some(field_meta) => { - // The type_option_data is serialized by protobuf. But the type_option_data should be - // serialized by utf-8 encoding. So we must transform the data here. - let type_option_json = type_option_json_str_from_bytes(type_option_data, &field_meta.field_type); - params.type_option_data = Some(type_option_json.as_bytes().to_vec()); - } - } - } + let deserializer = match self.pad.read().await.get_field(¶ms.field_id) { + None => return Err(ErrorCode::FieldDoesNotExist.into()), + Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()), + }; - let _ = self.modify(|grid| Ok(grid.update_field(params)?)).await?; + let _ = self.modify(|grid| Ok(grid.update_field(params, deserializer)?)).await?; let _ = self.notify_did_update_fields().await?; Ok(()) } @@ -126,6 +120,12 @@ impl ClientGridEditor { Ok(()) } + pub async fn switch_to_field_type(&self, field_id: &str, field_type: FieldType) -> FlowyResult { + let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; + let _ = self.notify_did_update_fields().await?; + todo!() + } + pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.duplicate_field(field_id)?)).await?; let _ = self.notify_did_update_fields().await?; @@ -402,3 +402,14 @@ impl RevisionCompactor for GridRevisionCompactor { Ok(delta.to_delta_bytes()) } } + +struct TypeOptionChangesetDeserializer(FieldType); +impl TypeOptionDataDeserializer for TypeOptionChangesetDeserializer { + fn deserialize(&self, type_option_data: Vec) -> CollaborateResult { + // The type_option_data is serialized by protobuf. But the type_option_data should be + // serialized by utf-8. So we must transform the data here. + + let type_option_json = type_option_json_str_from_bytes(type_option_data, &self.0); + Ok(type_option_json) + } +} 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 1b88e52ef7..b60aafedae 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -101,7 +101,7 @@ impl std::convert::From<&FieldMeta> for FieldOrder { } #[derive(Debug, Default, ProtoBuf)] -pub struct GetEditFieldContextParams { +pub struct GetEditFieldContextPayload { #[pb(index = 1)] pub grid_id: String, @@ -112,6 +112,38 @@ pub struct GetEditFieldContextParams { pub field_type: FieldType, } +#[derive(Debug, Default, ProtoBuf)] +pub struct EditFieldPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] + pub field_type: FieldType, +} + +pub struct EditFieldParams { + pub grid_id: String, + pub field_id: String, + pub field_type: FieldType, +} + +impl TryInto for EditFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + Ok(EditFieldParams { + grid_id: grid_id.0, + field_id: field_id.0, + field_type: self.field_type, + }) + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct EditFieldContext { #[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 6fdc3205e1..7d13585c86 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 @@ -1221,30 +1221,30 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { } #[derive(PartialEq,Clone,Default)] -pub struct GetEditFieldContextParams { +pub struct GetEditFieldContextPayload { // message fields pub grid_id: ::std::string::String, pub field_type: super::meta::FieldType, // message oneof groups - pub one_of_field_id: ::std::option::Option, + pub one_of_field_id: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GetEditFieldContextParams { - fn default() -> &'a GetEditFieldContextParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a GetEditFieldContextPayload { + fn default() -> &'a GetEditFieldContextPayload { + ::default_instance() } } #[derive(Clone,PartialEq,Debug)] -pub enum GetEditFieldContextParams_oneof_one_of_field_id { +pub enum GetEditFieldContextPayload_oneof_one_of_field_id { field_id(::std::string::String), } -impl GetEditFieldContextParams { - pub fn new() -> GetEditFieldContextParams { +impl GetEditFieldContextPayload { + pub fn new() -> GetEditFieldContextPayload { ::std::default::Default::default() } @@ -1279,7 +1279,7 @@ impl GetEditFieldContextParams { pub fn get_field_id(&self) -> &str { match self.one_of_field_id { - ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref v)) => v, + ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref v)) => v, _ => "", } } @@ -1289,24 +1289,24 @@ impl GetEditFieldContextParams { pub fn has_field_id(&self) -> bool { match self.one_of_field_id { - ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(..)) => true, + ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_field_id(&mut self, v: ::std::string::String) { - self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(v)) + self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(v)) } // Mutable pointer to the field. pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(_)) = self.one_of_field_id { + if let ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(_)) = self.one_of_field_id { } else { - self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(::std::string::String::new())); + self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(::std::string::String::new())); } match self.one_of_field_id { - ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref mut v)) => v, + ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref mut v)) => v, _ => panic!(), } } @@ -1315,7 +1315,7 @@ impl GetEditFieldContextParams { pub fn take_field_id(&mut self) -> ::std::string::String { if self.has_field_id() { match self.one_of_field_id.take() { - ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(v)) => v, + ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(v)) => v, _ => panic!(), } } else { @@ -1339,7 +1339,7 @@ impl GetEditFieldContextParams { } } -impl ::protobuf::Message for GetEditFieldContextParams { +impl ::protobuf::Message for GetEditFieldContextPayload { fn is_initialized(&self) -> bool { true } @@ -1355,7 +1355,7 @@ impl ::protobuf::Message for GetEditFieldContextParams { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextParams_oneof_one_of_field_id::field_id(is.read_string()?)); + self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(is.read_string()?)); }, 3 => { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 3, &mut self.unknown_fields)? @@ -1380,7 +1380,7 @@ impl ::protobuf::Message for GetEditFieldContextParams { } if let ::std::option::Option::Some(ref v) = self.one_of_field_id { match v { - &GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref v) => { + &GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref v) => { my_size += ::protobuf::rt::string_size(2, &v); }, }; @@ -1399,7 +1399,7 @@ impl ::protobuf::Message for GetEditFieldContextParams { } if let ::std::option::Option::Some(ref v) = self.one_of_field_id { match v { - &GetEditFieldContextParams_oneof_one_of_field_id::field_id(ref v) => { + &GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref v) => { os.write_string(2, v)?; }, }; @@ -1434,8 +1434,8 @@ impl ::protobuf::Message for GetEditFieldContextParams { Self::descriptor_static() } - fn new() -> GetEditFieldContextParams { - GetEditFieldContextParams::new() + fn new() -> GetEditFieldContextPayload { + GetEditFieldContextPayload::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1444,34 +1444,34 @@ impl ::protobuf::Message for GetEditFieldContextParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &GetEditFieldContextParams| { &m.grid_id }, - |m: &mut GetEditFieldContextParams| { &mut m.grid_id }, + |m: &GetEditFieldContextPayload| { &m.grid_id }, + |m: &mut GetEditFieldContextPayload| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "field_id", - GetEditFieldContextParams::has_field_id, - GetEditFieldContextParams::get_field_id, + GetEditFieldContextPayload::has_field_id, + GetEditFieldContextPayload::get_field_id, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "field_type", - |m: &GetEditFieldContextParams| { &m.field_type }, - |m: &mut GetEditFieldContextParams| { &mut m.field_type }, + |m: &GetEditFieldContextPayload| { &m.field_type }, + |m: &mut GetEditFieldContextPayload| { &mut m.field_type }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GetEditFieldContextParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GetEditFieldContextPayload", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GetEditFieldContextParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GetEditFieldContextParams::new) + fn default_instance() -> &'static GetEditFieldContextPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GetEditFieldContextPayload::new) } } -impl ::protobuf::Clear for GetEditFieldContextParams { +impl ::protobuf::Clear for GetEditFieldContextPayload { fn clear(&mut self) { self.grid_id.clear(); self.one_of_field_id = ::std::option::Option::None; @@ -1480,13 +1480,245 @@ impl ::protobuf::Clear for GetEditFieldContextParams { } } -impl ::std::fmt::Debug for GetEditFieldContextParams { +impl ::std::fmt::Debug for GetEditFieldContextPayload { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GetEditFieldContextParams { +impl ::protobuf::reflect::ProtobufValue for GetEditFieldContextPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct EditFieldPayload { + // message fields + pub grid_id: ::std::string::String, + pub field_id: ::std::string::String, + pub field_type: super::meta::FieldType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a EditFieldPayload { + fn default() -> &'a EditFieldPayload { + ::default_instance() + } +} + +impl EditFieldPayload { + pub fn new() -> EditFieldPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // .FieldType field_type = 3; + + + pub fn get_field_type(&self) -> super::meta::FieldType { + self.field_type + } + pub fn clear_field_type(&mut self) { + self.field_type = super::meta::FieldType::RichText; + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: super::meta::FieldType) { + self.field_type = v; + } +} + +impl ::protobuf::Message for EditFieldPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 3, &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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if self.field_type != super::meta::FieldType::RichText { + my_size += ::protobuf::rt::enum_size(3, self.field_type); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if self.field_type != super::meta::FieldType::RichText { + os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + 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() -> EditFieldPayload { + EditFieldPayload::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: &EditFieldPayload| { &m.grid_id }, + |m: &mut EditFieldPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &EditFieldPayload| { &m.field_id }, + |m: &mut EditFieldPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "field_type", + |m: &EditFieldPayload| { &m.field_type }, + |m: &mut EditFieldPayload| { &mut m.field_type }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "EditFieldPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static EditFieldPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(EditFieldPayload::new) + } +} + +impl ::protobuf::Clear for EditFieldPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_id.clear(); + self.field_type = super::meta::FieldType::RichText; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for EditFieldPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for EditFieldPayload { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -5513,49 +5745,52 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"K\n\x15FieldIdentifierParams\ \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\"\x8f\x01\n\x19GetEditFieldContextParams\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_i\ - d\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\ - \x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"|\n\x10EditFiel\ - dContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid\ - _field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option\ - _data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ - \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ - edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ - ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ - t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ - \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ - \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ - \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ - .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ - \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ - items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\ - \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ - \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ - \x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b\ - 2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\ - \x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\ - \x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01\ - (\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstart\ - RowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\ - \x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ - \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ - \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ - \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ - \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ - \x0f.GridBlockOrderR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ - \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ - \"<\n\x19CreateSelectOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\ - \x01(\tR\noptionNameb\x06proto3\ + \x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldContextPayloa\ + d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_\ + id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\ + \x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\n\x10EditFiel\ + dPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\ + \x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_type\x18\x03\ + \x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\x02\ + \x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\x03\ + \x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05items\ + \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ + RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ + lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ + yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ + \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ + (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ + \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ + \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ + \x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\ + \x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ + 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ + \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ + \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ + R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ + lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ + \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ + idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ + \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ + rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ + \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ + \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ + \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ + ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ + ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ + \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ + ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ + \x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ + \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ + kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"<\n\x19CreateSelec\ + tOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionNameb\ + \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 cba28ad711..6e4a4f31cf 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 @@ -26,11 +26,16 @@ message FieldIdentifierParams { message FieldOrder { string field_id = 1; } -message GetEditFieldContextParams { +message GetEditFieldContextPayload { string grid_id = 1; oneof one_of_field_id { string field_id = 2; }; FieldType field_type = 3; } +message EditFieldPayload { + string grid_id = 1; + string field_id = 2; + FieldType field_type = 3; +} message EditFieldContext { string grid_id = 1; Field grid_field = 2; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index d3e407a763..362fe924b0 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -20,6 +20,10 @@ pub struct GridMetaPad { pub(crate) delta: GridMetaDelta, } +pub trait TypeOptionDataDeserializer { + fn deserialize(&self, type_option_data: Vec) -> CollaborateResult; +} + impl GridMetaPad { pub fn from_delta(delta: GridMetaDelta) -> CollaborateResult { let s = delta.to_str()?; @@ -85,7 +89,11 @@ impl GridMetaPad { }) } - pub fn update_field(&mut self, changeset: FieldChangesetParams) -> CollaborateResult> { + pub fn update_field( + &mut self, + changeset: FieldChangesetParams, + deserializer: T, + ) -> CollaborateResult> { let field_id = changeset.field_id.clone(); self.modify_field(&field_id, |field| { let mut is_changed = None; @@ -120,7 +128,7 @@ impl GridMetaPad { } if let Some(type_option_data) = changeset.type_option_data { - match String::from_utf8(type_option_data) { + match deserializer.deserialize(type_option_data) { Ok(type_option_json) => { field.type_option_json = type_option_json; is_changed = Some(()) From e0b969595cae57835333529d9c75b74041628259 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 1 Apr 2022 16:38:51 +0800 Subject: [PATCH 081/179] chore: save type option data as map --- .../flowy-grid-data-model/meta.pb.dart | 59 +++- .../flowy-grid-data-model/meta.pbjson.dart | 25 +- .../rust-lib/flowy-grid/src/event_handler.rs | 8 +- frontend/rust-lib/flowy-grid/src/macros.rs | 84 ++--- .../src/services/field/field_builder.rs | 54 ++-- .../type_options/checkbox_type_option.rs | 25 +- .../field/type_options/date_type_option.rs | 19 +- .../src/services/field/type_options/mod.rs | 1 + .../field/type_options/number_type_option.rs | 16 +- .../type_options/selection_type_option.rs | 28 +- .../field/type_options/text_type_option.rs | 16 +- .../field/type_options/type_option_data.rs | 9 + .../flowy-grid/src/services/grid_editor.rs | 20 +- .../src/services/row/cell_data_serde.rs | 32 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 2 +- .../src/entities/meta.rs | 57 +++- .../src/protobuf/model/meta.rs | 295 ++++++++++++++---- .../src/protobuf/proto/meta.proto | 5 +- .../src/client_grid/grid_meta_pad.rs | 4 +- 19 files changed, 524 insertions(+), 235 deletions(-) create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index bc29686021..c391040543 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -215,7 +215,7 @@ class FieldMeta extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionJson') + ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionByFieldTypeId', subBuilder: TypeOptionDataByFieldTypeId.create) ..hasRequiredFields = false ; @@ -228,7 +228,7 @@ class FieldMeta extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - $core.String? typeOptionJson, + TypeOptionDataByFieldTypeId? typeOptionByFieldTypeId, }) { final _result = create(); if (id != null) { @@ -252,8 +252,8 @@ class FieldMeta extends $pb.GeneratedMessage { if (width != null) { _result.width = width; } - if (typeOptionJson != null) { - _result.typeOptionJson = typeOptionJson; + if (typeOptionByFieldTypeId != null) { + _result.typeOptionByFieldTypeId = typeOptionByFieldTypeId; } return _result; } @@ -342,13 +342,56 @@ class FieldMeta extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - $core.String get typeOptionJson => $_getSZ(7); + TypeOptionDataByFieldTypeId get typeOptionByFieldTypeId => $_getN(7); @$pb.TagNumber(8) - set typeOptionJson($core.String v) { $_setString(7, v); } + set typeOptionByFieldTypeId(TypeOptionDataByFieldTypeId v) { setField(8, v); } @$pb.TagNumber(8) - $core.bool hasTypeOptionJson() => $_has(7); + $core.bool hasTypeOptionByFieldTypeId() => $_has(7); @$pb.TagNumber(8) - void clearTypeOptionJson() => clearField(8); + void clearTypeOptionByFieldTypeId() => clearField(8); + @$pb.TagNumber(8) + TypeOptionDataByFieldTypeId ensureTypeOptionByFieldTypeId() => $_ensure(7); +} + +class TypeOptionDataByFieldTypeId extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TypeOptionDataByFieldTypeId', createEmptyInstance: create) + ..m<$core.String, $core.String>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'map', entryClassName: 'TypeOptionDataByFieldTypeId.MapEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OS) + ..hasRequiredFields = false + ; + + TypeOptionDataByFieldTypeId._() : super(); + factory TypeOptionDataByFieldTypeId({ + $core.Map<$core.String, $core.String>? map, + }) { + final _result = create(); + if (map != null) { + _result.map.addAll(map); + } + return _result; + } + factory TypeOptionDataByFieldTypeId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TypeOptionDataByFieldTypeId.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') + TypeOptionDataByFieldTypeId clone() => TypeOptionDataByFieldTypeId()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TypeOptionDataByFieldTypeId copyWith(void Function(TypeOptionDataByFieldTypeId) updates) => super.copyWith((message) => updates(message as TypeOptionDataByFieldTypeId)) as TypeOptionDataByFieldTypeId; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TypeOptionDataByFieldTypeId create() => TypeOptionDataByFieldTypeId._(); + TypeOptionDataByFieldTypeId createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TypeOptionDataByFieldTypeId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TypeOptionDataByFieldTypeId? _defaultInstance; + + @$pb.TagNumber(1) + $core.Map<$core.String, $core.String> get map => $_getMap(0); } enum FieldChangesetPayload_OneOfName { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 7c690f7b1e..74a4ffe802 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -69,12 +69,33 @@ const FieldMeta$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_option_json', '3': 8, '4': 1, '5': 9, '10': 'typeOptionJson'}, + const {'1': 'type_option_by_field_type_id', '3': 8, '4': 1, '5': 11, '6': '.TypeOptionDataByFieldTypeId', '10': 'typeOptionByFieldTypeId'}, ], }; /// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSKAoQdHlwZV9vcHRpb25fanNvbhgIIAEoCVIOdHlwZU9wdGlvbkpzb24='); +final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSWwocdHlwZV9vcHRpb25fYnlfZmllbGRfdHlwZV9pZBgIIAEoCzIcLlR5cGVPcHRpb25EYXRhQnlGaWVsZFR5cGVJZFIXdHlwZU9wdGlvbkJ5RmllbGRUeXBlSWQ='); +@$core.Deprecated('Use typeOptionDataByFieldTypeIdDescriptor instead') +const TypeOptionDataByFieldTypeId$json = const { + '1': 'TypeOptionDataByFieldTypeId', + '2': const [ + const {'1': 'map', '3': 1, '4': 3, '5': 11, '6': '.TypeOptionDataByFieldTypeId.MapEntry', '10': 'map'}, + ], + '3': const [TypeOptionDataByFieldTypeId_MapEntry$json], +}; + +@$core.Deprecated('Use typeOptionDataByFieldTypeIdDescriptor instead') +const TypeOptionDataByFieldTypeId_MapEntry$json = const { + '1': 'MapEntry', + '2': const [ + const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, + const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `TypeOptionDataByFieldTypeId`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List typeOptionDataByFieldTypeIdDescriptor = $convert.base64Decode('ChtUeXBlT3B0aW9uRGF0YUJ5RmllbGRUeXBlSWQSNwoDbWFwGAEgAygLMiUuVHlwZU9wdGlvbkRhdGFCeUZpZWxkVHlwZUlkLk1hcEVudHJ5UgNtYXAaNgoITWFwRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4AQ=='); @$core.Deprecated('Use fieldChangesetPayloadDescriptor instead') const FieldChangesetPayload$json = const { '1': 'FieldChangesetPayload', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 25f11c3010..53660bdea2 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,5 +1,5 @@ use crate::manager::GridManager; -use crate::services::field::{type_option_data_from_str, SelectOption}; +use crate::services::field::{type_option_builder_from_json_str, SelectOption}; use crate::services::grid_editor::ClientGridEditor; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; @@ -115,9 +115,11 @@ pub(crate) async fn get_field_context_handler( ) -> DataResult { let params = data.into_inner(); let editor = manager.get_grid_editor(¶ms.grid_id)?; - let mut field_meta = get_or_create_field_meta(¶ms, editor).await?; - let type_option_data = type_option_data_from_str(&field_meta.type_option_json, &field_meta.field_type); + let s = field_meta.get_type_option_str().unwrap(); + let builder = type_option_builder_from_json_str(&s, &field_meta.field_type); + let type_option_data = builder.entry().protobuf_bytes().to_vec(); + let field: Field = field_meta.into(); let edit_context = EditFieldContext { grid_id: params.grid_id, diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 932d93c6ed..2afa9eeda2 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -9,15 +9,16 @@ macro_rules! impl_into_box_type_option_builder { }; } -macro_rules! impl_from_json_str_and_from_bytes { +macro_rules! impl_builder_from_json_str_and_from_bytes { ($target: ident,$type_option: ident) => { impl $target { - pub fn from_json_str(s: &str) -> $target { - $target($type_option::from(s)) + pub fn from_protobuf_bytes(bytes: Bytes) -> $target { + let type_option = $type_option::from_protobuf_bytes(bytes); + $target(type_option) } - pub fn from_bytes(bytes: Bytes) -> $target { - let type_option = $type_option::try_from(bytes).unwrap_or($type_option::default()); + pub fn from_json_str(s: &str) -> $target { + let type_option = $type_option::from_json_str(s); $target(type_option) } } @@ -25,48 +26,33 @@ macro_rules! impl_from_json_str_and_from_bytes { } #[macro_export] -macro_rules! impl_from_and_to_type_option { +macro_rules! impl_type_option { ($target: ident, $field_type:expr) => { - impl_from_field_type_option!($target); - impl_to_field_type_option!($target, $field_type); - }; -} - -#[macro_export] -macro_rules! impl_from_field_type_option { - ($target: ident) => { impl std::convert::From<&FieldMeta> for $target { fn from(field_meta: &FieldMeta) -> $target { - $target::from(field_meta.type_option_json.as_str()) - } - } - - impl std::convert::From<&str> for $target { - fn from(type_option_str: &str) -> $target { - match serde_json::from_str(type_option_str) { - Ok(obj) => obj, - Err(err) => { - tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); - $target::default() - } + match field_meta + .type_option_by_field_type_id + .get_entry::<$target>(&$field_type) + { + None => $target::default(), + Some(target) => target, } } } - }; -} - -#[macro_export] -macro_rules! impl_to_field_type_option { - ($target: ident, $field_type:expr) => { - impl $target { - pub fn field_type(&self) -> FieldType { - $field_type - } - } impl std::convert::From<$target> for String { - fn from(field_description: $target) -> Self { - match serde_json::to_string(&field_description) { + fn from(type_option: $target) -> String { + type_option.json_str() + } + } + + impl TypeOptionDataEntry for $target { + fn field_type(&self) -> FieldType { + $field_type + } + + fn json_str(&self) -> String { + match serde_json::to_string(&self) { Ok(s) => s, Err(e) => { tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); @@ -74,6 +60,26 @@ macro_rules! impl_to_field_type_option { } } } + + fn protobuf_bytes(&self) -> Bytes { + self.clone().try_into().unwrap() + } + } + + impl TypeOptionDataFrom for $target { + fn from_json_str(s: &str) -> $target { + match serde_json::from_str(s) { + Ok(obj) => obj, + Err(err) => { + tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); + $target::default() + } + } + } + + fn from_protobuf_bytes(bytes: Bytes) -> $target { + $target::try_from(bytes).unwrap_or($target::default()) + } } }; } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 474a97e885..d978951425 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,6 +1,8 @@ use crate::services::field::type_options::*; use bytes::Bytes; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{ + Field, FieldMeta, FieldType, TypeOptionDataByFieldTypeId, TypeOptionDataEntry, TypeOptionDataFrom, +}; pub struct FieldBuilder { field_meta: FieldMeta, @@ -24,6 +26,23 @@ impl FieldBuilder { Self::new(type_option_builder) } + pub fn from_field(field: Field, type_option_builder: Box) -> Self { + let field_meta = FieldMeta { + id: field.id, + name: field.name, + desc: field.desc, + field_type: field.field_type, + frozen: field.frozen, + visibility: field.visibility, + width: field.width, + type_option_by_field_type_id: TypeOptionDataByFieldTypeId::default(), + }; + Self { + field_meta, + type_option_builder, + } + } + pub fn name(mut self, name: &str) -> Self { self.field_meta.name = name.to_owned(); self @@ -52,16 +71,16 @@ impl FieldBuilder { pub fn build(self) -> FieldMeta { debug_assert_eq!(self.field_meta.field_type, self.type_option_builder.field_type()); let mut field_meta = self.field_meta; - let type_option_json = self.type_option_builder.build_type_option_str(); - field_meta.type_option_json = type_option_json; + field_meta + .type_option_by_field_type_id + .insert_entry(self.type_option_builder.entry()); field_meta } } pub trait TypeOptionBuilder { fn field_type(&self) -> FieldType; - fn build_type_option_str(&self) -> String; - fn build_type_option_data(&self) -> Bytes; + fn entry(&self) -> &dyn TypeOptionDataEntry; } pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box { @@ -88,23 +107,14 @@ pub fn type_option_builder_from_json_str(s: &str, field_type: &FieldType) -> Box } } -pub fn type_option_builder_from_bytes(bytes: Bytes, field_type: &FieldType) -> Box { +pub fn type_option_builder_from_bytes>(bytes: T, field_type: &FieldType) -> Box { + let bytes = bytes.into(); match field_type { - FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_bytes(bytes)), - FieldType::Number => Box::new(NumberTypeOptionBuilder::from_bytes(bytes)), - FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_bytes(bytes)), - FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_bytes(bytes)), - FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_bytes(bytes)), - FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_bytes(bytes)), + FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_protobuf_bytes(bytes)), + FieldType::Number => Box::new(NumberTypeOptionBuilder::from_protobuf_bytes(bytes)), + FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_protobuf_bytes(bytes)), + FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_protobuf_bytes(bytes)), + FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_protobuf_bytes(bytes)), + FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_protobuf_bytes(bytes)), } } - -pub fn type_option_data_from_str(s: &str, field_type: &FieldType) -> Vec { - let builder = type_option_builder_from_json_str(s, field_type); - builder.build_type_option_data().to_vec() -} - -pub fn type_option_json_str_from_bytes(bytes: Vec, field_type: &FieldType) -> String { - let builder = type_option_builder_from_bytes(Bytes::from(bytes), field_type); - builder.build_type_option_str() -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index f6e07c831a..99fd2290db 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,16 +1,19 @@ -use crate::impl_from_and_to_type_option; -use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; +use crate::impl_type_option; +use crate::services::field::{ + BoxTypeOptionBuilder, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RichTextTypeOption, + SingleSelectTypeOption, TypeOptionBuilder, +}; use crate::services::row::CellDataSerde; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; use serde::{Deserialize, Serialize}; #[derive(Default)] pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption); impl_into_box_type_option_builder!(CheckboxTypeOptionBuilder); -impl_from_json_str_and_from_bytes!(CheckboxTypeOptionBuilder, CheckboxTypeOption); +impl_builder_from_json_str_and_from_bytes!(CheckboxTypeOptionBuilder, CheckboxTypeOption); impl CheckboxTypeOptionBuilder { pub fn set_selected(mut self, is_selected: bool) -> Self { @@ -24,12 +27,8 @@ impl TypeOptionBuilder for CheckboxTypeOptionBuilder { self.0.field_type() } - fn build_type_option_str(&self) -> String { - self.0.clone().into() - } - - fn build_type_option_data(&self) -> Bytes { - self.0.clone().try_into().unwrap() + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 } } @@ -38,7 +37,7 @@ pub struct CheckboxTypeOption { #[pb(index = 1)] pub is_selected: bool, } -impl_from_and_to_type_option!(CheckboxTypeOption, FieldType::Checkbox); +impl_type_option!(CheckboxTypeOption, FieldType::Checkbox); impl CellDataSerde for CheckboxTypeOption { fn deserialize_cell_data(&self, data: String) -> String { @@ -47,8 +46,8 @@ impl CellDataSerde for CheckboxTypeOption { fn serialize_cell_data(&self, data: &str) -> Result { let s = match string_to_bool(data) { - true => "1", - false => "0", + true => "No", + false => "Yes", }; Ok(s.to_owned()) } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index dca1654b3e..92d01cf90b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,15 +1,14 @@ -use crate::impl_from_and_to_type_option; +use crate::impl_type_option; use crate::services::row::CellDataSerde; 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::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; use serde::{Deserialize, Serialize}; -use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; +use crate::services::field::{BoxTypeOptionBuilder, RichTextTypeOption, TypeOptionBuilder}; use strum_macros::EnumIter; // Date @@ -21,7 +20,7 @@ pub struct DateTypeOption { #[pb(index = 2)] pub time_format: TimeFormat, } -impl_from_and_to_type_option!(DateTypeOption, FieldType::DateTime); +impl_type_option!(DateTypeOption, FieldType::DateTime); impl DateTypeOption { #[allow(dead_code)] @@ -66,7 +65,7 @@ impl CellDataSerde for DateTypeOption { #[derive(Default)] pub struct DateTypeOptionBuilder(DateTypeOption); impl_into_box_type_option_builder!(DateTypeOptionBuilder); -impl_from_json_str_and_from_bytes!(DateTypeOptionBuilder, DateTypeOption); +impl_builder_from_json_str_and_from_bytes!(DateTypeOptionBuilder, DateTypeOption); impl DateTypeOptionBuilder { pub fn date_format(mut self, date_format: DateFormat) -> Self { @@ -84,12 +83,8 @@ impl TypeOptionBuilder for DateTypeOptionBuilder { self.0.field_type() } - fn build_type_option_str(&self) -> String { - self.0.clone().into() - } - - fn build_type_option_data(&self) -> Bytes { - self.0.clone().try_into().unwrap() + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs index 958edf2664..b5cab79b97 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/mod.rs @@ -3,6 +3,7 @@ mod date_type_option; mod number_type_option; mod selection_type_option; mod text_type_option; +mod type_option_data; pub use checkbox_type_option::*; pub use date_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 67de271309..fc052df8e7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -1,8 +1,8 @@ -use crate::impl_from_and_to_type_option; +use crate::impl_type_option; use crate::services::row::CellDataSerde; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; use lazy_static::lazy_static; use rust_decimal::prelude::Zero; use rust_decimal::Decimal; @@ -22,7 +22,7 @@ lazy_static! { #[derive(Default)] pub struct NumberTypeOptionBuilder(NumberTypeOption); impl_into_box_type_option_builder!(NumberTypeOptionBuilder); -impl_from_json_str_and_from_bytes!(NumberTypeOptionBuilder, NumberTypeOption); +impl_builder_from_json_str_and_from_bytes!(NumberTypeOptionBuilder, NumberTypeOption); impl NumberTypeOptionBuilder { pub fn name(mut self, name: &str) -> Self { @@ -51,12 +51,8 @@ impl TypeOptionBuilder for NumberTypeOptionBuilder { self.0.field_type() } - fn build_type_option_str(&self) -> String { - self.0.clone().into() - } - - fn build_type_option_data(&self) -> Bytes { - self.0.clone().try_into().unwrap() + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 } } @@ -78,7 +74,7 @@ pub struct NumberTypeOption { #[pb(index = 5)] pub name: String, } -impl_from_and_to_type_option!(NumberTypeOption, FieldType::Number); +impl_type_option!(NumberTypeOption, FieldType::Number); impl std::default::Default for NumberTypeOption { fn default() -> Self { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 015bf2257b..c712c747ec 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,11 +1,11 @@ -use crate::impl_from_and_to_type_option; +use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -21,7 +21,7 @@ pub struct SingleSelectTypeOption { #[pb(index = 2)] pub disable_color: bool, } -impl_from_and_to_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); +impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); impl CellDataSerde for SingleSelectTypeOption { fn deserialize_cell_data(&self, data: String) -> String { @@ -36,7 +36,7 @@ impl CellDataSerde for SingleSelectTypeOption { #[derive(Default)] pub struct SingleSelectTypeOptionBuilder(SingleSelectTypeOption); impl_into_box_type_option_builder!(SingleSelectTypeOptionBuilder); -impl_from_json_str_and_from_bytes!(SingleSelectTypeOptionBuilder, SingleSelectTypeOption); +impl_builder_from_json_str_and_from_bytes!(SingleSelectTypeOptionBuilder, SingleSelectTypeOption); impl SingleSelectTypeOptionBuilder { pub fn option(mut self, opt: SelectOption) -> Self { @@ -50,12 +50,8 @@ impl TypeOptionBuilder for SingleSelectTypeOptionBuilder { self.0.field_type() } - fn build_type_option_str(&self) -> String { - self.0.clone().into() - } - - fn build_type_option_data(&self) -> Bytes { - self.0.clone().try_into().unwrap() + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 } } @@ -68,7 +64,7 @@ pub struct MultiSelectTypeOption { #[pb(index = 2)] pub disable_color: bool, } -impl_from_and_to_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); +impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); impl CellDataSerde for MultiSelectTypeOption { fn deserialize_cell_data(&self, data: String) -> String { @@ -83,7 +79,7 @@ impl CellDataSerde for MultiSelectTypeOption { #[derive(Default)] pub struct MultiSelectTypeOptionBuilder(MultiSelectTypeOption); impl_into_box_type_option_builder!(MultiSelectTypeOptionBuilder); -impl_from_json_str_and_from_bytes!(MultiSelectTypeOptionBuilder, MultiSelectTypeOption); +impl_builder_from_json_str_and_from_bytes!(MultiSelectTypeOptionBuilder, MultiSelectTypeOption); impl MultiSelectTypeOptionBuilder { pub fn option(mut self, opt: SelectOption) -> Self { self.0.options.push(opt); @@ -96,12 +92,8 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder { self.0.field_type() } - fn build_type_option_str(&self) -> String { - self.0.clone().into() - } - - fn build_type_option_data(&self) -> Bytes { - self.0.clone().try_into().unwrap() + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 3b2cfa051d..a1441f28c7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,28 +1,24 @@ -use crate::impl_from_and_to_type_option; +use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; use serde::{Deserialize, Serialize}; #[derive(Default)] pub struct RichTextTypeOptionBuilder(RichTextTypeOption); impl_into_box_type_option_builder!(RichTextTypeOptionBuilder); -impl_from_json_str_and_from_bytes!(RichTextTypeOptionBuilder, RichTextTypeOption); +impl_builder_from_json_str_and_from_bytes!(RichTextTypeOptionBuilder, RichTextTypeOption); impl TypeOptionBuilder for RichTextTypeOptionBuilder { fn field_type(&self) -> FieldType { self.0.field_type() } - fn build_type_option_str(&self) -> String { - self.0.clone().into() - } - - fn build_type_option_data(&self) -> Bytes { - self.0.clone().try_into().unwrap() + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 } } @@ -31,7 +27,7 @@ pub struct RichTextTypeOption { #[pb(index = 1)] pub format: String, } -impl_from_and_to_type_option!(RichTextTypeOption, FieldType::RichText); +impl_type_option!(RichTextTypeOption, FieldType::RichText); impl CellDataSerde for RichTextTypeOption { fn deserialize_cell_data(&self, data: String) -> String { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs new file mode 100644 index 0000000000..330cc4fb10 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs @@ -0,0 +1,9 @@ +use flowy_grid_data_model::entities::FieldType; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +// #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +// pub struct TypeOptionData { +// #[pb(index = 1)] +// pub map: HashMap, +// } 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 3b48f244d5..226949a5d2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{type_option_json_str_from_bytes, FieldBuilder}; +use crate::services::field::{type_option_builder_from_bytes, FieldBuilder}; use crate::services::row::*; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; @@ -74,17 +74,9 @@ impl ClientGridEditor { }; Ok(grid.update_field(changeset, deserializer)?) } else { - let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); - let field_meta = FieldMeta { - id: field.id, - name: field.name, - desc: field.desc, - field_type: field.field_type, - frozen: field.frozen, - visibility: field.visibility, - width: field.width, - type_option_json, - }; + // let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); + let builder = type_option_builder_from_bytes(type_option_data, &field.field_type); + let field_meta = FieldBuilder::from_field(field, builder).build(); Ok(grid.create_field(field_meta, start_field_id)?) } }) @@ -409,7 +401,7 @@ impl TypeOptionDataDeserializer for TypeOptionChangesetDeserializer { // The type_option_data is serialized by protobuf. But the type_option_data should be // serialized by utf-8. So we must transform the data here. - let type_option_json = type_option_json_str_from_bytes(type_option_data, &self.0); - Ok(type_option_json) + let builder = type_option_builder_from_bytes(type_option_data, &self.0); + Ok(builder.entry().json_str()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs index 3d1c1939d7..1e60583df8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs @@ -8,25 +8,25 @@ pub trait CellDataSerde { } #[allow(dead_code)] -pub fn serialize_cell_data(data: &str, field: &FieldMeta) -> Result { - match field.field_type { - FieldType::RichText => RichTextTypeOption::from(field).serialize_cell_data(data), - FieldType::Number => NumberTypeOption::from(field).serialize_cell_data(data), - FieldType::DateTime => DateTypeOption::from(field).serialize_cell_data(data), - FieldType::SingleSelect => SingleSelectTypeOption::from(field).serialize_cell_data(data), - FieldType::MultiSelect => MultiSelectTypeOption::from(field).serialize_cell_data(data), - FieldType::Checkbox => CheckboxTypeOption::from(field).serialize_cell_data(data), +pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result { + match field_meta.field_type { + FieldType::RichText => RichTextTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::Number => NumberTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::DateTime => DateTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).serialize_cell_data(data), } } -pub fn deserialize_cell_data(data: String, field: &FieldMeta) -> Result { - let s = match field.field_type { - FieldType::RichText => RichTextTypeOption::from(field).deserialize_cell_data(data), - FieldType::Number => NumberTypeOption::from(field).deserialize_cell_data(data), - FieldType::DateTime => DateTypeOption::from(field).deserialize_cell_data(data), - FieldType::SingleSelect => SingleSelectTypeOption::from(field).deserialize_cell_data(data), - FieldType::MultiSelect => MultiSelectTypeOption::from(field).deserialize_cell_data(data), - FieldType::Checkbox => CheckboxTypeOption::from(field).deserialize_cell_data(data), +pub fn deserialize_cell_data(data: String, field_meta: &FieldMeta) -> Result { + let s = match field_meta.field_type { + FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data), + FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data), + FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data), }; Ok(s) } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 7739356531..49fc16bb5a 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,7 +3,7 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, Field, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, + BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_grid_data_model::parser::CreateFieldParams; diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 90074cadff..a09ced64b8 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,8 +1,11 @@ use crate::parser::NotEmptyUuid; +use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; use serde::{Deserialize, Serialize}; +use std::any::Any; use std::collections::HashMap; +use std::ops::Deref; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; @@ -76,7 +79,7 @@ pub struct GridBlockMetaSerde { pub row_metas: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct FieldMeta { #[pb(index = 1)] pub id: String, @@ -100,7 +103,7 @@ pub struct FieldMeta { pub width: i32, #[pb(index = 8)] - pub type_option_json: String, + pub type_option_by_field_type_id: TypeOptionDataByFieldTypeId, } impl FieldMeta { @@ -113,7 +116,55 @@ impl FieldMeta { frozen: false, visibility: true, width: DEFAULT_FIELD_WIDTH, - type_option_json: Default::default(), + type_option_by_field_type_id: Default::default(), + } + } + + pub fn get_type_option_str(&self) -> Option { + match self.type_option_by_field_type_id.get(&self.field_type) { + None => None, + Some(s) => Some(s.to_owned()), + } + } +} + +pub trait TypeOptionDataEntry { + fn field_type(&self) -> FieldType; + fn json_str(&self) -> String; + fn protobuf_bytes(&self) -> Bytes; +} + +pub trait TypeOptionDataFrom { + fn from_json_str(s: &str) -> Self; + fn from_protobuf_bytes(bytes: Bytes) -> Self; +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +pub struct TypeOptionDataByFieldTypeId { + #[pb(index = 1)] + pub map: HashMap, +} + +impl TypeOptionDataByFieldTypeId { + pub fn insert_entry(&mut self, entry: &T) { + self.map.insert(entry.field_type().type_id(), entry.json_str()); + } + + pub fn insert(&mut self, field_type: &FieldType, json_str: String) { + self.map.insert(field_type.type_id(), json_str); + } + + pub fn get_entry(&self, field_type: &FieldType) -> Option { + match self.map.get(&field_type.type_id()) { + None => None, + Some(s) => Some(T::from_json_str(s)), + } + } + + pub fn get(&self, field_type: &FieldType) -> Option { + match self.map.get(&field_type.type_id()) { + None => None, + Some(s) => Some(s.to_owned()), } } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index f22a7c00a2..4b0de2d3fb 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -727,7 +727,7 @@ pub struct FieldMeta { pub frozen: bool, pub visibility: bool, pub width: i32, - pub type_option_json: ::std::string::String, + pub type_option_by_field_type_id: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -882,35 +882,47 @@ impl FieldMeta { self.width = v; } - // string type_option_json = 8; + // .TypeOptionDataByFieldTypeId type_option_by_field_type_id = 8; - pub fn get_type_option_json(&self) -> &str { - &self.type_option_json + pub fn get_type_option_by_field_type_id(&self) -> &TypeOptionDataByFieldTypeId { + self.type_option_by_field_type_id.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_type_option_json(&mut self) { - self.type_option_json.clear(); + pub fn clear_type_option_by_field_type_id(&mut self) { + self.type_option_by_field_type_id.clear(); + } + + pub fn has_type_option_by_field_type_id(&self) -> bool { + self.type_option_by_field_type_id.is_some() } // Param is passed by value, moved - pub fn set_type_option_json(&mut self, v: ::std::string::String) { - self.type_option_json = v; + pub fn set_type_option_by_field_type_id(&mut self, v: TypeOptionDataByFieldTypeId) { + self.type_option_by_field_type_id = ::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_option_json(&mut self) -> &mut ::std::string::String { - &mut self.type_option_json + pub fn mut_type_option_by_field_type_id(&mut self) -> &mut TypeOptionDataByFieldTypeId { + if self.type_option_by_field_type_id.is_none() { + self.type_option_by_field_type_id.set_default(); + } + self.type_option_by_field_type_id.as_mut().unwrap() } // Take field - pub fn take_type_option_json(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_option_json, ::std::string::String::new()) + pub fn take_type_option_by_field_type_id(&mut self) -> TypeOptionDataByFieldTypeId { + self.type_option_by_field_type_id.take().unwrap_or_else(|| TypeOptionDataByFieldTypeId::new()) } } impl ::protobuf::Message for FieldMeta { fn is_initialized(&self) -> bool { + for v in &self.type_option_by_field_type_id { + if !v.is_initialized() { + return false; + } + }; true } @@ -952,7 +964,7 @@ impl ::protobuf::Message for FieldMeta { self.width = tmp; }, 8 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_option_json)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_option_by_field_type_id)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -987,8 +999,9 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } - if !self.type_option_json.is_empty() { - my_size += ::protobuf::rt::string_size(8, &self.type_option_json); + if let Some(ref v) = self.type_option_by_field_type_id.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); @@ -1017,8 +1030,10 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { os.write_int32(7, self.width)?; } - if !self.type_option_json.is_empty() { - os.write_string(8, &self.type_option_json)?; + if let Some(ref v) = self.type_option_by_field_type_id.as_ref() { + os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1093,10 +1108,10 @@ impl ::protobuf::Message for FieldMeta { |m: &FieldMeta| { &m.width }, |m: &mut FieldMeta| { &mut m.width }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_option_json", - |m: &FieldMeta| { &m.type_option_json }, - |m: &mut FieldMeta| { &mut m.type_option_json }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "type_option_by_field_type_id", + |m: &FieldMeta| { &m.type_option_by_field_type_id }, + |m: &mut FieldMeta| { &mut m.type_option_by_field_type_id }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldMeta", @@ -1121,7 +1136,7 @@ impl ::protobuf::Clear for FieldMeta { self.frozen = false; self.visibility = false; self.width = 0; - self.type_option_json.clear(); + self.type_option_by_field_type_id.clear(); self.unknown_fields.clear(); } } @@ -1138,6 +1153,160 @@ impl ::protobuf::reflect::ProtobufValue for FieldMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct TypeOptionDataByFieldTypeId { + // message fields + pub map: ::std::collections::HashMap<::std::string::String, ::std::string::String>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a TypeOptionDataByFieldTypeId { + fn default() -> &'a TypeOptionDataByFieldTypeId { + ::default_instance() + } +} + +impl TypeOptionDataByFieldTypeId { + pub fn new() -> TypeOptionDataByFieldTypeId { + ::std::default::Default::default() + } + + // repeated .TypeOptionDataByFieldTypeId.MapEntry map = 1; + + + pub fn get_map(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { + &self.map + } + pub fn clear_map(&mut self) { + self.map.clear(); + } + + // Param is passed by value, moved + pub fn set_map(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { + self.map = v; + } + + // Mutable pointer to the field. + pub fn mut_map(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { + &mut self.map + } + + // Take field + pub fn take_map(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { + ::std::mem::replace(&mut self.map, ::std::collections::HashMap::new()) + } +} + +impl ::protobuf::Message for TypeOptionDataByFieldTypeId { + 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_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.map)?; + }, + _ => { + ::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; + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.map); + 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<()> { + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.map, 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() -> TypeOptionDataByFieldTypeId { + TypeOptionDataByFieldTypeId::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_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( + "map", + |m: &TypeOptionDataByFieldTypeId| { &m.map }, + |m: &mut TypeOptionDataByFieldTypeId| { &mut m.map }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TypeOptionDataByFieldTypeId", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static TypeOptionDataByFieldTypeId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TypeOptionDataByFieldTypeId::new) + } +} + +impl ::protobuf::Clear for TypeOptionDataByFieldTypeId { + fn clear(&mut self) { + self.map.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for TypeOptionDataByFieldTypeId { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for TypeOptionDataByFieldTypeId { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct FieldChangesetPayload { // message fields @@ -3507,51 +3676,55 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\ aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\ - metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xe6\x01\n\tFieldM\ + metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\x99\x02\n\tFieldM\ eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ - idth\x12(\n\x10type_option_json\x18\x08\x20\x01(\tR\x0etypeOptionJson\"\ - \xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ - \x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ - \x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n\ - .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\ - \x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibi\ - lity\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10ty\ - pe_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of\ - _nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_fro\ - zenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_\ - type_option_data\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\t\ - R\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\ - \n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08blo\ - ck_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\ - \x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\ - \x06height\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\ - \x20\x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.C\ - ellMetaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\ - \x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\ - \x01(\x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\ - \nvisibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaCh\ - angeset.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\ + idth\x12[\n\x1ctype_option_by_field_type_id\x18\x08\x20\x01(\x0b2\x1c.Ty\ + peOptionDataByFieldTypeIdR\x17typeOptionByFieldTypeId\"\x8e\x01\n\x1bTyp\ + eOptionDataByFieldTypeId\x127\n\x03map\x18\x01\x20\x03(\x0b2%.TypeOption\ + DataByFieldTypeId.MapEntryR\x03map\x1a6\n\x08MapEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05va\ + lue:\x028\x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\ + \x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\ + \x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\ + \x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\ + \x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\ + \x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\ + \x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\ + \x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\ + \r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\ + \n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\ + \x19\n\x17one_of_type_option_data\"8\n\x07AnyData\x12\x17\n\x07type_id\ + \x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\ + \x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ + id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_b\ + y_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellBy\ + FieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nv\ + isibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\ \x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\ - \x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\ - \n\x11one_of_visibility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\ - \x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\ - \x83\x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\ - \x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\ - \x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridCont\ - ext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\ - \x12/\n\x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMe\ - tas\x12;\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSer\ - deR\rblockMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\ - \x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSele\ - ct\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\ - \x05b\x06proto3\ + \x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChan\ + geset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06heig\ + ht\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\ + \x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\ + \x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12Cel\ + lByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ + \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\ro\ + ne_of_heightB\x13\n\x11one_of_visibility\"9\n\x08CellMeta\x12\x19\n\x08f\ + ield_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01\ + (\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05ro\ + wId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04da\ + ta\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10Bui\ + ldGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\n\ + fieldMetas\x12/\n\x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMeta\ + R\nblockMetas\x12;\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBl\ + ockMetaSerdeR\rblockMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\ + \x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSi\ + ngleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbo\ + x\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 2c5bd41f86..897143247b 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -22,7 +22,10 @@ message FieldMeta { bool frozen = 5; bool visibility = 6; int32 width = 7; - string type_option_json = 8; + TypeOptionDataByFieldTypeId type_option_by_field_type_id = 8; +} +message TypeOptionDataByFieldTypeId { + map map = 1; } message FieldChangesetPayload { string field_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 362fe924b0..5d7085e92c 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -129,8 +129,8 @@ impl GridMetaPad { if let Some(type_option_data) = changeset.type_option_data { match deserializer.deserialize(type_option_data) { - Ok(type_option_json) => { - field.type_option_json = type_option_json; + Ok(json_str) => { + field.type_option_by_field_type_id.insert(&field.field_type, json_str); is_changed = Some(()) } Err(err) => { From 915d71991a75ffb3a33ea7fb530052c89d124090 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 1 Apr 2022 22:46:01 +0800 Subject: [PATCH 082/179] chore: save multi type option data --- .../rust-lib/flowy-grid/src/event_handler.rs | 59 ++++++++++++++----- .../flowy-grid/src/services/grid_editor.rs | 20 +++++-- .../src/client_grid/grid_meta_pad.rs | 34 ++++++++++- 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 53660bdea2..e15c113484 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,5 +1,5 @@ use crate::manager::GridManager; -use crate::services::field::{type_option_builder_from_json_str, SelectOption}; +use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str, SelectOption}; use crate::services::grid_editor::ClientGridEditor; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; @@ -85,7 +85,19 @@ pub(crate) async fn switch_to_field_handler( ) -> DataResult { let params: EditFieldParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let edit_context = editor.switch_to_field_type(¶ms.field_id, params.field_type).await?; + editor + .switch_to_field_type(¶ms.field_id, ¶ms.field_type) + .await?; + + let field_meta = editor.get_field(¶ms.field_id).await?; + let edit_context = make_field_edit_context( + ¶ms.grid_id, + Some(params.field_id), + params.field_type, + editor, + field_meta, + ) + .await?; data_result(edit_context) } @@ -115,31 +127,46 @@ pub(crate) async fn get_field_context_handler( ) -> DataResult { let params = data.into_inner(); let editor = manager.get_grid_editor(¶ms.grid_id)?; - let mut field_meta = get_or_create_field_meta(¶ms, editor).await?; - let s = field_meta.get_type_option_str().unwrap(); - let builder = type_option_builder_from_json_str(&s, &field_meta.field_type); - let type_option_data = builder.entry().protobuf_bytes().to_vec(); + let edit_context = + make_field_edit_context(¶ms.grid_id, params.field_id, params.field_type, editor, None).await?; - let field: Field = field_meta.into(); - let edit_context = EditFieldContext { - grid_id: params.grid_id, - grid_field: field, - type_option_data, - }; data_result(edit_context) } +async fn make_field_edit_context( + grid_id: &str, + field_id: Option, + field_type: FieldType, + editor: Arc, + field_meta: Option, +) -> FlowyResult { + let field_meta = field_meta.unwrap_or(get_or_create_field_meta(field_id, &field_type, editor).await?); + let s = field_meta + .get_type_option_str() + .unwrap_or_else(|| default_type_option_builder_from_type(&field_type).entry().json_str()); + + let builder = type_option_builder_from_json_str(&s, &field_meta.field_type); + let type_option_data = builder.entry().protobuf_bytes().to_vec(); + let field: Field = field_meta.into(); + Ok(EditFieldContext { + grid_id: grid_id.to_string(), + grid_field: field, + type_option_data, + }) +} + async fn get_or_create_field_meta( - params: &GetEditFieldContextPayload, + field_id: Option, + field_type: &FieldType, editor: Arc, ) -> FlowyResult { - if params.field_id.is_some() { - if let Some(field_meta) = editor.get_field(params.field_id.as_ref().unwrap()).await? { + if field_id.is_some() { + if let Some(field_meta) = editor.get_field(field_id.as_ref().unwrap()).await? { return Ok(field_meta); } } - editor.default_field_meta(¶ms.field_type).await + editor.create_next_field_meta(field_type).await } #[tracing::instrument(level = "debug", skip(data, manager), err)] 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 226949a5d2..3ca651f5dc 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,10 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{type_option_builder_from_bytes, FieldBuilder}; +use crate::services::field::{ + default_type_option_builder_from_type, type_option_builder_from_bytes, type_option_builder_from_json_str, + FieldBuilder, +}; use crate::services::row::*; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; @@ -85,7 +88,7 @@ impl ClientGridEditor { Ok(()) } - pub async fn default_field_meta(&self, field_type: &FieldType) -> FlowyResult { + pub async fn create_next_field_meta(&self, field_type: &FieldType) -> FlowyResult { let name = format!("Property {}", self.pad.read().await.fields().len() + 1); let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build(); Ok(field_meta) @@ -95,7 +98,7 @@ impl ClientGridEditor { self.pad.read().await.contain_field(field_id) } - pub async fn update_field(&self, mut params: FieldChangesetParams) -> FlowyResult<()> { + pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let deserializer = match self.pad.read().await.get_field(¶ms.field_id) { None => return Err(ErrorCode::FieldDoesNotExist.into()), Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()), @@ -112,10 +115,15 @@ impl ClientGridEditor { Ok(()) } - pub async fn switch_to_field_type(&self, field_id: &str, field_type: FieldType) -> FlowyResult { - let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; + pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> { + let type_option_json_builder = + |field_type: &FieldType| -> String { default_type_option_builder_from_type(field_type).entry().json_str() }; + + let _ = self + .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) + .await?; let _ = self.notify_did_update_fields().await?; - todo!() + Ok(()) } pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 5d7085e92c..eac4b97be9 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -3,7 +3,8 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ - FieldChangesetParams, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, + FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta, + RepeatedFieldOrder, TypeOptionDataEntry, }; use lib_infra::uuid; @@ -89,6 +90,37 @@ impl GridMetaPad { }) } + pub fn switch_to_field( + &mut self, + field_id: &str, + field_type: FieldType, + type_option_json_builder: B, + ) -> CollaborateResult> + where + B: FnOnce(&FieldType) -> String, + { + self.modify_grid(|grid| { + // + match grid.fields.iter_mut().find(|field_meta| field_meta.id == field_id) { + None => { + tracing::warn!("Can not find the field with id: {}", field_id); + Ok(None) + } + Some(field_meta) => { + if field_meta.get_type_option_str().is_none() { + let type_option_json = type_option_json_builder(&field_type); + field_meta + .type_option_by_field_type_id + .insert(&field_type, type_option_json); + } + + field_meta.field_type = field_type; + Ok(Some(())) + } + } + }) + } + pub fn update_field( &mut self, changeset: FieldChangesetParams, From 82eed0506b1809ae2b9d1063c698537608942e3f Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 1 Apr 2022 22:49:26 +0800 Subject: [PATCH 083/179] chore: fix warnings --- .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-grid/src/macros.rs | 7 +-- .../src/services/field/field_builder.rs | 8 +-- .../type_options/checkbox_type_option.rs | 7 +-- .../field/type_options/date_type_option.rs | 4 +- .../field/type_options/number_type_option.rs | 2 +- .../type_options/selection_type_option.rs | 2 +- .../field/type_options/text_type_option.rs | 2 +- .../field/type_options/type_option_data.rs | 4 -- .../flowy-grid/src/services/grid_editor.rs | 5 +- .../flowy-grid/tests/grid/grid_test.rs | 15 ++--- .../rust-lib/flowy-grid/tests/grid/script.rs | 22 +++++-- .../src/entities/meta.rs | 60 ++++++++++--------- .../src/client_grid/grid_meta_pad.rs | 13 ++-- 14 files changed, 75 insertions(+), 78 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e15c113484..e90998b986 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -142,7 +142,7 @@ async fn make_field_edit_context( ) -> FlowyResult { let field_meta = field_meta.unwrap_or(get_or_create_field_meta(field_id, &field_type, editor).await?); let s = field_meta - .get_type_option_str() + .get_type_option_str(None) .unwrap_or_else(|| default_type_option_builder_from_type(&field_type).entry().json_str()); let builder = type_option_builder_from_json_str(&s, &field_meta.field_type); diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 2afa9eeda2..4a4994729c 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -30,10 +30,7 @@ macro_rules! impl_type_option { ($target: ident, $field_type:expr) => { impl std::convert::From<&FieldMeta> for $target { fn from(field_meta: &FieldMeta) -> $target { - match field_meta - .type_option_by_field_type_id - .get_entry::<$target>(&$field_type) - { + match field_meta.get_type_option_entry::<$target>(Some($field_type)) { None => $target::default(), Some(target) => target, } @@ -66,7 +63,7 @@ macro_rules! impl_type_option { } } - impl TypeOptionDataFrom for $target { + impl TypeOptionDataEntity for $target { fn from_json_str(s: &str) -> $target { match serde_json::from_str(s) { Ok(obj) => obj, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index d978951425..9a654d4c43 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,8 +1,6 @@ use crate::services::field::type_options::*; use bytes::Bytes; -use flowy_grid_data_model::entities::{ - Field, FieldMeta, FieldType, TypeOptionDataByFieldTypeId, TypeOptionDataEntry, TypeOptionDataFrom, -}; +use flowy_grid_data_model::entities::{Field, FieldMeta, FieldType, TypeOptionDataByFieldTypeId, TypeOptionDataEntry}; pub struct FieldBuilder { field_meta: FieldMeta, @@ -71,9 +69,7 @@ impl FieldBuilder { pub fn build(self) -> FieldMeta { debug_assert_eq!(self.field_meta.field_type, self.type_option_builder.field_type()); let mut field_meta = self.field_meta; - field_meta - .type_option_by_field_type_id - .insert_entry(self.type_option_builder.entry()); + field_meta.insert_type_option_entry(self.type_option_builder.entry()); field_meta } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 99fd2290db..3611f5a0db 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,13 +1,10 @@ use crate::impl_type_option; -use crate::services::field::{ - BoxTypeOptionBuilder, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RichTextTypeOption, - SingleSelectTypeOption, TypeOptionBuilder, -}; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::CellDataSerde; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; #[derive(Default)] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 92d01cf90b..86c15e13c5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -5,10 +5,10 @@ use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; -use crate::services::field::{BoxTypeOptionBuilder, RichTextTypeOption, TypeOptionBuilder}; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use strum_macros::EnumIter; // Date diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index fc052df8e7..7e557955df 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -2,7 +2,7 @@ use crate::impl_type_option; use crate::services::row::CellDataSerde; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use lazy_static::lazy_static; use rust_decimal::prelude::Zero; use rust_decimal::Decimal; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index c712c747ec..abc9c81288 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -5,7 +5,7 @@ use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index a1441f28c7..6bffc8606f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -4,7 +4,7 @@ use crate::services::row::CellDataSerde; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry, TypeOptionDataFrom}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; #[derive(Default)] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs index 330cc4fb10..fbba14feab 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs @@ -1,7 +1,3 @@ -use flowy_grid_data_model::entities::FieldType; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - // #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] // pub struct TypeOptionData { // #[pb(index = 1)] diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 3ca651f5dc..edfce7a736 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,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_bytes, type_option_builder_from_json_str, - FieldBuilder, -}; +use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::row::*; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 31ee76712e..138ccf4bba 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -6,7 +6,8 @@ use flowy_grid::services::field::{ }; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, + CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, + TypeOptionDataEntry, }; #[tokio::test] @@ -55,7 +56,7 @@ async fn grid_create_duplicate_field() { async fn grid_update_field_with_empty_change() { let mut test = GridEditorTest::new().await; let (params, field_meta) = create_single_select_field(&test.grid_id); - let changeset = FieldChangeset { + let changeset = FieldChangesetParams { field_id: field_meta.id.clone(), grid_id: test.grid_id.clone(), name: None, @@ -84,9 +85,9 @@ async fn grid_update_field() { let (single_select_params, single_select_field) = create_single_select_field(&test.grid_id); let mut cloned_field = single_select_field.clone(); - let mut single_select_type_options = SingleSelectTypeOption::from(&single_select_field); - single_select_type_options.options.push(SelectOption::new("Unknown")); - let changeset = FieldChangeset { + let mut single_select_type_option = SingleSelectTypeOption::from(&single_select_field); + single_select_type_option.options.push(SelectOption::new("Unknown")); + let changeset = FieldChangesetParams { field_id: single_select_field.id.clone(), grid_id: test.grid_id.clone(), name: None, @@ -95,12 +96,12 @@ async fn grid_update_field() { frozen: Some(true), visibility: None, width: Some(1000), - type_option_data: Some(single_select_type_options.clone().into()), + type_option_data: Some(single_select_type_option.protobuf_bytes().to_vec()), }; cloned_field.frozen = true; cloned_field.width = 1000; - cloned_field.type_option_json = single_select_type_options.into(); + cloned_field.insert_type_option_entry(&single_select_type_option); let scripts = vec![ CreateField { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 49fc16bb5a..4dbb5c7a0c 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,10 +3,9 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, - GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, + BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldType, + GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, }; -use flowy_grid_data_model::parser::CreateFieldParams; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_sync::client_grid::GridBuilder; use flowy_test::helper::ViewTest; @@ -22,7 +21,7 @@ pub enum EditorScript { params: CreateFieldParams, }, UpdateField { - changeset: FieldChangeset, + changeset: FieldChangesetParams, }, DeleteField { field_meta: FieldMeta, @@ -255,6 +254,12 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { let cloned_field_meta = field_meta.clone(); + let type_option_data = field_meta + .get_type_option_entry::(None) + .unwrap() + .protobuf_bytes() + .to_vec(); + let field = Field { id: field_meta.id, name: field_meta.name, @@ -268,7 +273,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { let params = CreateFieldParams { grid_id: grid_id.to_owned(), field, - type_option_data: field_meta.type_option_json.as_bytes().to_vec(), + type_option_data, start_field_id: None, }; (params, cloned_field_meta) @@ -281,6 +286,11 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet let field_meta = FieldBuilder::new(single_select).name("Name").visibility(true).build(); let cloned_field_meta = field_meta.clone(); + let type_option_data = field_meta + .get_type_option_entry::(None) + .unwrap() + .protobuf_bytes() + .to_vec(); let field = Field { id: field_meta.id, @@ -295,7 +305,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet let params = CreateFieldParams { grid_id: grid_id.to_owned(), field, - type_option_data: field_meta.type_option_json.as_bytes().to_vec(), + type_option_data, start_field_id: None, }; (params, cloned_field_meta) diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index a09ced64b8..ad81fc532a 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -3,9 +3,7 @@ use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; use serde::{Deserialize, Serialize}; -use std::any::Any; use std::collections::HashMap; -use std::ops::Deref; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; @@ -79,7 +77,7 @@ pub struct GridBlockMetaSerde { pub row_metas: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, Eq, PartialEq)] pub struct FieldMeta { #[pb(index = 1)] pub id: String, @@ -120,11 +118,27 @@ impl FieldMeta { } } - pub fn get_type_option_str(&self) -> Option { - match self.type_option_by_field_type_id.get(&self.field_type) { - None => None, - Some(s) => Some(s.to_owned()), - } + pub fn insert_type_option_entry(&mut self, entry: &T) { + self.type_option_by_field_type_id + .insert(entry.field_type().type_id(), entry.json_str()); + } + + pub fn get_type_option_entry(&self, field_type: Option) -> Option { + let field_type = field_type.as_ref().unwrap_or(&self.field_type); + self.type_option_by_field_type_id + .get(&field_type.type_id()) + .map(|s| T::from_json_str(s)) + } + + pub fn insert_type_option_str(&mut self, field_type: &FieldType, json_str: String) { + self.type_option_by_field_type_id.insert(field_type.type_id(), json_str); + } + + pub fn get_type_option_str(&self, field_type: Option) -> Option { + let field_type = field_type.as_ref().unwrap_or(&self.field_type); + self.type_option_by_field_type_id + .get(&field_type.type_id()) + .map(|s| s.to_owned()) } } @@ -134,38 +148,28 @@ pub trait TypeOptionDataEntry { fn protobuf_bytes(&self) -> Bytes; } -pub trait TypeOptionDataFrom { +pub trait TypeOptionDataEntity { fn from_json_str(s: &str) -> Self; fn from_protobuf_bytes(bytes: Bytes) -> Self; } -#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf, PartialEq, Eq)] pub struct TypeOptionDataByFieldTypeId { #[pb(index = 1)] pub map: HashMap, } -impl TypeOptionDataByFieldTypeId { - pub fn insert_entry(&mut self, entry: &T) { - self.map.insert(entry.field_type().type_id(), entry.json_str()); - } +impl std::ops::Deref for TypeOptionDataByFieldTypeId { + type Target = HashMap; - pub fn insert(&mut self, field_type: &FieldType, json_str: String) { - self.map.insert(field_type.type_id(), json_str); + fn deref(&self) -> &Self::Target { + &self.map } +} - pub fn get_entry(&self, field_type: &FieldType) -> Option { - match self.map.get(&field_type.type_id()) { - None => None, - Some(s) => Some(T::from_json_str(s)), - } - } - - pub fn get(&self, field_type: &FieldType) -> Option { - match self.map.get(&field_type.type_id()) { - None => None, - Some(s) => Some(s.to_owned()), - } +impl std::ops::DerefMut for TypeOptionDataByFieldTypeId { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.map } } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index eac4b97be9..2d32fd1d9e 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -4,13 +4,13 @@ use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta, - RepeatedFieldOrder, TypeOptionDataEntry, + RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; -use std::string::FromUtf8Error; + use std::sync::Arc; pub type GridMetaDelta = PlainTextDelta; @@ -107,11 +107,9 @@ impl GridMetaPad { Ok(None) } Some(field_meta) => { - if field_meta.get_type_option_str().is_none() { + if field_meta.get_type_option_str(Some(field_type.clone())).is_none() { let type_option_json = type_option_json_builder(&field_type); - field_meta - .type_option_by_field_type_id - .insert(&field_type, type_option_json); + field_meta.insert_type_option_str(&field_type, type_option_json); } field_meta.field_type = field_type; @@ -162,7 +160,8 @@ impl GridMetaPad { if let Some(type_option_data) = changeset.type_option_data { match deserializer.deserialize(type_option_data) { Ok(json_str) => { - field.type_option_by_field_type_id.insert(&field.field_type, json_str); + let field_type = field.field_type.clone(); + field.insert_type_option_str(&field_type, json_str); is_changed = Some(()) } Err(err) => { From 2262dd0d7b4f95aaef8af34b6974ddeff15e820e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 2 Apr 2022 10:54:01 +0800 Subject: [PATCH 084/179] chore: get cell metas --- .../flowy-grid-data-model/meta.pb.dart | 36 ++++----- .../flowy-grid-data-model/meta.pbjson.dart | 14 ++-- .../src/services/block_meta_editor.rs | 71 +++++++++--------- .../flowy-grid/src/services/grid_editor.rs | 75 +++++++++---------- .../flowy-grid/src/services/row/row_loader.rs | 59 +++++++-------- .../rust-lib/flowy-grid/tests/grid/script.rs | 2 +- .../src/entities/meta.rs | 6 +- .../src/protobuf/model/meta.rs | 74 +++++++++--------- .../src/protobuf/proto/meta.proto | 4 +- .../src/client_grid/grid_block_meta_pad.rs | 29 +++++-- .../src/client_grid/grid_builder.rs | 4 +- .../src/client_grid/grid_meta_pad.rs | 6 +- 12 files changed, 191 insertions(+), 189 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index c391040543..9e730b17d2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -151,15 +151,15 @@ class GridBlockMeta extends $pb.GeneratedMessage { void clearRowCount() => clearField(3); } -class GridBlockMetaSerde extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaSerde', createEmptyInstance: create) +class GridBlockMetaData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..hasRequiredFields = false ; - GridBlockMetaSerde._() : super(); - factory GridBlockMetaSerde({ + GridBlockMetaData._() : super(); + factory GridBlockMetaData({ $core.String? blockId, $core.Iterable? rowMetas, }) { @@ -172,26 +172,26 @@ class GridBlockMetaSerde extends $pb.GeneratedMessage { } return _result; } - factory GridBlockMetaSerde.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlockMetaSerde.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - GridBlockMetaSerde clone() => GridBlockMetaSerde()..mergeFromMessage(this); + GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GridBlockMetaSerde copyWith(void Function(GridBlockMetaSerde) updates) => super.copyWith((message) => updates(message as GridBlockMetaSerde)) as GridBlockMetaSerde; // ignore: deprecated_member_use + GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GridBlockMetaSerde create() => GridBlockMetaSerde._(); - GridBlockMetaSerde createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlockMetaData create() => GridBlockMetaData._(); + GridBlockMetaData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridBlockMetaSerde getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlockMetaSerde? _defaultInstance; + static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMetaData? _defaultInstance; @$pb.TagNumber(1) $core.String get blockId => $_getSZ(0); @@ -1078,7 +1078,7 @@ class BuildGridContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', subBuilder: GridBlockMeta.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaSerde.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaData.create) ..hasRequiredFields = false ; @@ -1086,7 +1086,7 @@ class BuildGridContext extends $pb.GeneratedMessage { factory BuildGridContext({ $core.Iterable? fieldMetas, GridBlockMeta? blockMetas, - GridBlockMetaSerde? blockMetaData, + GridBlockMetaData? blockMetaData, }) { final _result = create(); if (fieldMetas != null) { @@ -1136,14 +1136,14 @@ class BuildGridContext extends $pb.GeneratedMessage { GridBlockMeta ensureBlockMetas() => $_ensure(1); @$pb.TagNumber(3) - GridBlockMetaSerde get blockMetaData => $_getN(2); + GridBlockMetaData get blockMetaData => $_getN(2); @$pb.TagNumber(3) - set blockMetaData(GridBlockMetaSerde v) { setField(3, v); } + set blockMetaData(GridBlockMetaData v) { setField(3, v); } @$pb.TagNumber(3) $core.bool hasBlockMetaData() => $_has(2); @$pb.TagNumber(3) void clearBlockMetaData() => clearField(3); @$pb.TagNumber(3) - GridBlockMetaSerde ensureBlockMetaData() => $_ensure(2); + GridBlockMetaData ensureBlockMetaData() => $_ensure(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 74a4ffe802..65e813160f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -47,17 +47,17 @@ const GridBlockMeta$json = const { /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); -@$core.Deprecated('Use gridBlockMetaSerdeDescriptor instead') -const GridBlockMetaSerde$json = const { - '1': 'GridBlockMetaSerde', +@$core.Deprecated('Use gridBlockMetaDataDescriptor instead') +const GridBlockMetaData$json = const { + '1': 'GridBlockMetaData', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'}, ], }; -/// Descriptor for `GridBlockMetaSerde`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaSerdeDescriptor = $convert.base64Decode('ChJHcmlkQmxvY2tNZXRhU2VyZGUSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSJQoJcm93X21ldGFzGAIgAygLMgguUm93TWV0YVIIcm93TWV0YXM='); +/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw=='); @$core.Deprecated('Use fieldMetaDescriptor instead') const FieldMeta$json = const { '1': 'FieldMeta', @@ -220,9 +220,9 @@ const BuildGridContext$json = const { '2': const [ const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, const {'1': 'block_metas', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, - const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaSerde', '10': 'blockMetaData'}, + const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'blockMetaData'}, ], }; /// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi8KC2Jsb2NrX21ldGFzGAIgASgLMg4uR3JpZEJsb2NrTWV0YVIKYmxvY2tNZXRhcxI7Cg9ibG9ja19tZXRhX2RhdGEYAyABKAsyEy5HcmlkQmxvY2tNZXRhU2VyZGVSDWJsb2NrTWV0YURhdGE='); +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi8KC2Jsb2NrX21ldGFzGAIgASgLMg4uR3JpZEJsb2NrTWV0YVIKYmxvY2tNZXRhcxI6Cg9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVINYmxvY2tNZXRhRGF0YQ=='); diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 65e80136c3..58e8e2ca9e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,12 +1,12 @@ -use crate::manager::GridUser; -use crate::services::row::{make_cell, make_row_ids_per_block, GridBlockMetaData}; -use bytes::Bytes; - use crate::dart_notification::{send_dart_notification, GridNotification}; +use crate::manager::GridUser; +use crate::services::row::{make_cell, make_row_ids_per_block, GridBlockSnapshot}; +use bytes::Bytes; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta, RowMetaChangeset, RowOrder, + CellMeta, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta, + RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{ @@ -116,7 +116,8 @@ impl GridBlockMetaEditorManager { pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult>> { let editor = self.get_editor(block_id).await?; - let mut row_metas = editor.get_row_metas(Some(vec![row_id.to_owned()])).await?; + let row_ids = vec![row_id.to_owned()]; + let mut row_metas = editor.get_row_metas(&Some(row_ids)).await?; if row_metas.is_empty() { Ok(None) } else { @@ -131,42 +132,35 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub(crate) async fn get_block_meta_data_from_blocks( - &self, - grid_blocks: Vec, - ) -> FlowyResult> { + pub(crate) async fn make_block_snapshots(&self, block_ids: Vec) -> FlowyResult> { let mut snapshots = vec![]; - for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.block_id).await?; - let row_metas = editor.get_row_metas(None).await?; + for block_id in block_ids { + let editor = self.get_editor(&block_id).await?; + let row_metas = editor.get_row_metas(&None).await?; row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - snapshots.push(GridBlockMetaData { - block_id: grid_block.block_id, - row_metas, - }); + snapshots.push(GridBlockSnapshot { block_id, row_metas }); } Ok(snapshots) } - pub(crate) async fn get_block_meta_data(&self, block_ids: &[String]) -> FlowyResult> { - let mut snapshots = vec![]; + // Optimization: Using the shared memory(Arc, Cow,etc.) to reduce memory usage. + pub async fn get_cell_metas( + &self, + block_ids: Option, + field_id: &str, + row_ids: Option>, + ) -> FlowyResult> { + let mut block_cell_metas = vec![]; for block_id in block_ids { - let editor = self.get_editor(block_id).await?; - let row_metas = editor.get_row_metas(None).await?; - row_metas.iter().for_each(|row_meta| { - self.block_id_by_row_id - .insert(row_meta.id.clone(), row_meta.block_id.clone()); - }); - snapshots.push(GridBlockMetaData { - block_id: block_id.clone(), - row_metas, - }); + let editor = self.get_editor(&block_id).await?; + let cell_metas = editor.get_cell_metas(field_id, &row_ids).await?; + block_cell_metas.extend(cell_metas); } - Ok(snapshots) + Ok(block_cell_metas) } async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { @@ -178,10 +172,7 @@ impl GridBlockMetaEditorManager { ); Err(FlowyError::internal().context(msg)) } - Some(block_id) => { - let editor = self.get_editor(&block_id).await?; - Ok(editor) - } + Some(block_id) => Ok(self.get_editor(&block_id).await?), } } @@ -301,7 +292,8 @@ impl ClientGridBlockMetaEditor { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult { let row_id = changeset.row_id.clone(); let _ = self.modify(|pad| Ok(pad.update_row(changeset)?)).await?; - let mut row_metas = self.get_row_metas(Some(vec![row_id.clone()])).await?; + let row_ids = vec![row_id.clone()]; + let mut row_metas = self.get_row_metas(&Some(row_ids)).await?; debug_assert_eq!(row_metas.len(), 1); if row_metas.is_empty() { @@ -312,12 +304,17 @@ impl ClientGridBlockMetaEditor { } } - pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { + pub async fn get_row_metas(&self, row_ids: &Option>) -> FlowyResult>> { let row_metas = self.pad.read().await.get_row_metas(row_ids)?; Ok(row_metas) } - pub async fn get_row_orders(&self, row_ids: Option>) -> FlowyResult> { + pub async fn get_cell_metas(&self, field_id: &str, row_ids: &Option>) -> FlowyResult> { + let cell_metas = self.pad.read().await.get_cell_metas(field_id, row_ids)?; + Ok(cell_metas) + } + + pub async fn get_row_orders(&self, row_ids: &Option>) -> FlowyResult> { let row_orders = self .pad .read() 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 edfce7a736..88738aa082 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -37,8 +37,9 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = - Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, pad.read().await.get_blocks().clone()).await?); + let block_meta_manager = Arc::new( + GridBlockMetaEditorManager::new(grid_id, &user, pad.read().await.get_block_metas().clone()).await?, + ); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -113,8 +114,11 @@ impl ClientGridEditor { } pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> { - let type_option_json_builder = - |field_type: &FieldType| -> String { default_type_option_builder_from_type(field_type).entry().json_str() }; + // let cell_metas = self.block_meta_manager.get_cell_metas(None, field_id, None).await?; + + let type_option_json_builder = |field_type: &FieldType| -> String { + return default_type_option_builder_from_type(field_type).entry().json_str(); + }; let _ = self .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) @@ -137,12 +141,12 @@ impl ClientGridEditor { } pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; + let _ = self.modify(|grid| Ok(grid.create_block_meta(grid_block)?)).await?; Ok(()) } pub async fn update_block(&self, changeset: GridBlockMetaChangeset) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?; + let _ = self.modify(|grid| Ok(grid.update_block_meta(changeset)?)).await?; Ok(()) } @@ -192,12 +196,15 @@ impl ClientGridEditor { pub async fn get_rows(&self, block_id: &str) -> FlowyResult { let block_ids = vec![block_id.to_owned()]; - let mut block_meta_data_vec = self.get_block_meta_data_vec(Some(&block_ids)).await?; - debug_assert_eq!(block_meta_data_vec.len(), 1); - if block_meta_data_vec.len() == 1 { - let block_meta_data = block_meta_data_vec.pop().unwrap(); + let mut grid_block_snapshot = self.grid_block_snapshots(Some(block_ids)).await?; + + // For the moment, we only support one block. + // We can save the rows into multiple blocks and load them asynchronously in the future. + debug_assert_eq!(grid_block_snapshot.len(), 1); + if grid_block_snapshot.len() == 1 { + let snapshot = grid_block_snapshot.pop().unwrap(); let field_metas = self.get_field_metas(None).await?; - let rows = make_rows_from_row_metas(&field_metas, &block_meta_data.row_metas); + let rows = make_rows_from_row_metas(&field_metas, &snapshot.row_metas); Ok(rows.into()) } else { Ok(vec![].into()) @@ -240,15 +247,12 @@ impl ClientGridEditor { } pub async fn get_blocks(&self, block_ids: Option>) -> FlowyResult { - let block_meta_data_vec = self.get_block_meta_data_vec(block_ids.as_ref()).await?; - match block_ids { - None => make_grid_blocks(block_meta_data_vec), - Some(block_ids) => make_grid_block_from_block_metas(&block_ids, block_meta_data_vec), - } + let block_snapshots = self.grid_block_snapshots(block_ids.clone()).await?; + make_grid_blocks(block_ids, block_snapshots) } pub async fn get_block_metas(&self) -> FlowyResult> { - let grid_blocks = self.pad.read().await.get_blocks(); + let grid_blocks = self.pad.read().await.get_block_metas(); Ok(grid_blocks) } @@ -266,7 +270,7 @@ impl ClientGridEditor { .pad .read() .await - .get_blocks() + .get_block_metas() .into_iter() .map(|grid_block_meta| GridBlockOrder { block_id: grid_block_meta.block_id, @@ -285,27 +289,18 @@ impl ClientGridEditor { Ok(field_metas) } - pub async fn get_block_meta_data_vec( - &self, - block_ids: Option<&Vec>, - ) -> FlowyResult> { - match block_ids { - None => { - let grid_blocks = self.pad.read().await.get_blocks(); - let row_metas_per_block = self - .block_meta_manager - .get_block_meta_data_from_blocks(grid_blocks) - .await?; - Ok(row_metas_per_block) - } - Some(block_ids) => { - let row_metas_per_block = self - .block_meta_manager - .get_block_meta_data(block_ids.as_slice()) - .await?; - Ok(row_metas_per_block) - } - } + pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { + let block_ids = block_ids.unwrap_or( + self.pad + .read() + .await + .get_block_metas() + .into_iter() + .map(|block_meta| block_meta.block_id) + .collect::>(), + ); + let snapshots = self.block_meta_manager.make_block_snapshots(block_ids).await?; + Ok(snapshots) } pub async fn delta_bytes(&self) -> Bytes { @@ -347,7 +342,7 @@ impl ClientGridEditor { } async fn block_id(&self) -> FlowyResult { - match self.pad.read().await.get_blocks().last() { + match self.pad.read().await.get_block_metas().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), Some(grid_block) => Ok(grid_block.block_id.clone()), } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 70cea1b4c8..55ee0ec8c8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -22,7 +22,7 @@ impl RowIdsPerBlock { } } -pub struct GridBlockMetaData { +pub struct GridBlockSnapshot { pub(crate) block_id: String, pub row_metas: Vec>, } @@ -40,20 +40,6 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec>() } -pub(crate) fn make_grid_blocks(block_meta_snapshots: Vec) -> FlowyResult { - Ok(block_meta_snapshots - .into_iter() - .map(|block_meta_data| { - let row_orders = make_row_orders_from_row_metas(&block_meta_data.row_metas); - GridBlock { - id: block_meta_data.block_id, - row_orders, - } - }) - .collect::>() - .into()) -} - #[inline(always)] pub fn make_cell( field_map: &HashMap<&String, &FieldMeta>, @@ -101,25 +87,36 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc>() } -pub(crate) fn make_grid_block_from_block_metas( - block_ids: &[String], - block_meta_data_vec: Vec, +pub(crate) fn make_grid_blocks( + block_ids: Option>, + block_snapshots: Vec, ) -> FlowyResult { - let block_meta_data_map: HashMap<&String, &Vec>> = block_meta_data_vec - .iter() - .map(|data| (&data.block_id, &data.row_metas)) - .collect(); + match block_ids { + None => Ok(block_snapshots + .into_iter() + .map(|snapshot| { + let row_orders = make_row_orders_from_row_metas(&snapshot.row_metas); + GridBlock::new(&snapshot.block_id, row_orders) + }) + .collect::>() + .into()), + Some(block_ids) => { + let block_meta_data_map: HashMap<&String, &Vec>> = block_snapshots + .iter() + .map(|data| (&data.block_id, &data.row_metas)) + .collect(); - let mut grid_blocks = vec![]; - for block_id in block_ids { - match block_meta_data_map.get(&block_id) { - None => {} - Some(row_metas) => { - let row_orders = make_row_orders_from_row_metas(row_metas); - grid_blocks.push(GridBlock::new(block_id, row_orders)); + let mut grid_blocks = vec![]; + for block_id in block_ids { + match block_meta_data_map.get(&block_id) { + None => {} + Some(row_metas) => { + let row_orders = make_row_orders_from_row_metas(row_metas); + grid_blocks.push(GridBlock::new(&block_id, row_orders)); + } + } } + Ok(grid_blocks.into()) } } - - Ok(grid_blocks.into()) } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 4dbb5c7a0c..858e9826cf 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -238,7 +238,7 @@ impl GridEditorTest { async fn get_row_metas(editor: &Arc) -> Vec> { editor - .get_block_meta_data_vec(None) + .grid_block_snapshots(None) .await .unwrap() .pop() diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index ad81fc532a..edb5236139 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -69,7 +69,7 @@ impl GridBlockMetaChangeset { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlockMetaSerde { +pub struct GridBlockMetaData { #[pb(index = 1)] pub block_id: String, @@ -431,13 +431,13 @@ pub struct BuildGridContext { pub block_metas: GridBlockMeta, #[pb(index = 3)] - pub block_meta_data: GridBlockMetaSerde, + pub block_meta_data: GridBlockMetaData, } impl std::default::Default for BuildGridContext { fn default() -> Self { let grid_block = GridBlockMeta::new(); - let grid_block_meta_data = GridBlockMetaSerde { + let grid_block_meta_data = GridBlockMetaData { block_id: grid_block.block_id.clone(), row_metas: vec![], }; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4b0de2d3fb..97e14eb738 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -510,7 +510,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } #[derive(PartialEq,Clone,Default)] -pub struct GridBlockMetaSerde { +pub struct GridBlockMetaData { // message fields pub block_id: ::std::string::String, pub row_metas: ::protobuf::RepeatedField, @@ -519,14 +519,14 @@ pub struct GridBlockMetaSerde { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridBlockMetaSerde { - fn default() -> &'a GridBlockMetaSerde { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlockMetaData { + fn default() -> &'a GridBlockMetaData { + ::default_instance() } } -impl GridBlockMetaSerde { - pub fn new() -> GridBlockMetaSerde { +impl GridBlockMetaData { + pub fn new() -> GridBlockMetaData { ::std::default::Default::default() } @@ -582,7 +582,7 @@ impl GridBlockMetaSerde { } } -impl ::protobuf::Message for GridBlockMetaSerde { +impl ::protobuf::Message for GridBlockMetaData { fn is_initialized(&self) -> bool { for v in &self.row_metas { if !v.is_initialized() { @@ -665,8 +665,8 @@ impl ::protobuf::Message for GridBlockMetaSerde { Self::descriptor_static() } - fn new() -> GridBlockMetaSerde { - GridBlockMetaSerde::new() + fn new() -> GridBlockMetaData { + GridBlockMetaData::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -675,29 +675,29 @@ impl ::protobuf::Message for GridBlockMetaSerde { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &GridBlockMetaSerde| { &m.block_id }, - |m: &mut GridBlockMetaSerde| { &mut m.block_id }, + |m: &GridBlockMetaData| { &m.block_id }, + |m: &mut GridBlockMetaData| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "row_metas", - |m: &GridBlockMetaSerde| { &m.row_metas }, - |m: &mut GridBlockMetaSerde| { &mut m.row_metas }, + |m: &GridBlockMetaData| { &m.row_metas }, + |m: &mut GridBlockMetaData| { &mut m.row_metas }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlockMetaSerde", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMetaData", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridBlockMetaSerde { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlockMetaSerde::new) + fn default_instance() -> &'static GridBlockMetaData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMetaData::new) } } -impl ::protobuf::Clear for GridBlockMetaSerde { +impl ::protobuf::Clear for GridBlockMetaData { fn clear(&mut self) { self.block_id.clear(); self.row_metas.clear(); @@ -705,13 +705,13 @@ impl ::protobuf::Clear for GridBlockMetaSerde { } } -impl ::std::fmt::Debug for GridBlockMetaSerde { +impl ::std::fmt::Debug for GridBlockMetaData { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridBlockMetaSerde { +impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3331,7 +3331,7 @@ pub struct BuildGridContext { // message fields pub field_metas: ::protobuf::RepeatedField, pub block_metas: ::protobuf::SingularPtrField, - pub block_meta_data: ::protobuf::SingularPtrField, + pub block_meta_data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3406,11 +3406,11 @@ impl BuildGridContext { self.block_metas.take().unwrap_or_else(|| GridBlockMeta::new()) } - // .GridBlockMetaSerde block_meta_data = 3; + // .GridBlockMetaData block_meta_data = 3; - pub fn get_block_meta_data(&self) -> &GridBlockMetaSerde { - self.block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_block_meta_data(&self) -> &GridBlockMetaData { + self.block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) } pub fn clear_block_meta_data(&mut self) { self.block_meta_data.clear(); @@ -3421,13 +3421,13 @@ impl BuildGridContext { } // Param is passed by value, moved - pub fn set_block_meta_data(&mut self, v: GridBlockMetaSerde) { + pub fn set_block_meta_data(&mut self, v: GridBlockMetaData) { self.block_meta_data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_block_meta_data(&mut self) -> &mut GridBlockMetaSerde { + pub fn mut_block_meta_data(&mut self) -> &mut GridBlockMetaData { if self.block_meta_data.is_none() { self.block_meta_data.set_default(); } @@ -3435,8 +3435,8 @@ impl BuildGridContext { } // Take field - pub fn take_block_meta_data(&mut self) -> GridBlockMetaSerde { - self.block_meta_data.take().unwrap_or_else(|| GridBlockMetaSerde::new()) + pub fn take_block_meta_data(&mut self) -> GridBlockMetaData { + self.block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new()) } } @@ -3566,7 +3566,7 @@ impl ::protobuf::Message for BuildGridContext { |m: &BuildGridContext| { &m.block_metas }, |m: &mut BuildGridContext| { &mut m.block_metas }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "block_meta_data", |m: &BuildGridContext| { &m.block_meta_data }, |m: &mut BuildGridContext| { &mut m.block_meta_data }, @@ -3674,10 +3674,10 @@ static file_descriptor_proto_data: &'static [u8] = b"\ s\x12/\n\x0bblock_metas\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\nblockM\ etas\"o\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\ ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ - \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\ - aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\ - metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\x99\x02\n\tFieldM\ - eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ + \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMet\ + aData\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_m\ + etas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\x99\x02\n\tFieldMe\ + ta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ @@ -3717,11 +3717,11 @@ static file_descriptor_proto_data: &'static [u8] = b"\ (\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\ \x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05ro\ wId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04da\ - ta\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10Bui\ + ta\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\"\xac\x01\n\x10Bui\ ldGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\n\ fieldMetas\x12/\n\x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMeta\ - R\nblockMetas\x12;\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBl\ - ockMetaSerdeR\rblockMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\ + R\nblockMetas\x12:\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBl\ + ockMetaDataR\rblockMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\ \x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSi\ ngleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbo\ x\x10\x05b\x06proto3\ diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 897143247b..ca00b88b57 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -10,7 +10,7 @@ message GridBlockMeta { int32 start_row_index = 2; int32 row_count = 3; } -message GridBlockMetaSerde { +message GridBlockMetaData { string block_id = 1; repeated RowMeta row_metas = 2; } @@ -68,7 +68,7 @@ message CellMetaChangeset { message BuildGridContext { repeated FieldMeta field_metas = 1; GridBlockMeta block_metas = 2; - GridBlockMetaSerde block_meta_data = 3; + GridBlockMetaData block_meta_data = 3; } enum FieldType { RichText = 0; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 768c7bf60a..0b9459a625 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -1,10 +1,11 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMetaSerde, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; +use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; @@ -25,12 +26,12 @@ impl GridBlockMetaPad { let s = delta.to_str()?; tracing::info!("delta: {}", delta); tracing::info!("{}", s); - let block_meta: GridBlockMetaSerde = serde_json::from_str(&s).map_err(|e| { + let meta_data: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { let msg = format!("Deserialize delta to block meta failed: {}", e); CollaborateError::internal().context(msg) })?; - let block_id = block_meta.block_id; - let rows = block_meta + let block_id = meta_data.block_id; + let rows = meta_data .row_metas .into_iter() .map(Arc::new) @@ -78,7 +79,7 @@ impl GridBlockMetaPad { }) } - pub fn get_row_metas(&self, row_ids: Option>) -> CollaborateResult>> { + pub fn get_row_metas(&self, row_ids: &Option>) -> CollaborateResult>> { match row_ids { None => Ok(self.row_metas.to_vec()), Some(row_ids) => { @@ -102,6 +103,18 @@ impl GridBlockMetaPad { } } + pub fn get_cell_metas(&self, field_id: &str, row_ids: &Option>) -> CollaborateResult> { + let rows = self.get_row_metas(row_ids)?; + let cell_metas = rows + .iter() + .flat_map(|row| { + let cell_meta = row.cell_by_field_id.get(field_id)?; + Some(cell_meta.clone()) + }) + .collect::>(); + Ok(cell_metas) + } + pub fn number_of_rows(&self) -> i32 { self.row_metas.len() as i32 } @@ -186,12 +199,12 @@ pub struct GridBlockMetaChange { pub md5: String, } -pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaSerde) -> GridBlockMetaDelta { +pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta { let json = serde_json::to_string(&grid_block_meta_data).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaSerde) -> RepeatedRevision { +pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision { let delta = make_block_meta_delta(grid_block_meta_data); let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes); @@ -200,7 +213,7 @@ pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlock impl std::default::Default for GridBlockMetaPad { fn default() -> Self { - let block_meta_data = GridBlockMetaSerde { + let block_meta_data = GridBlockMetaData { block_id: uuid(), row_metas: vec![], }; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs index 2875a8968c..2b91e1352c 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs @@ -41,7 +41,7 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { mod tests { use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; - use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaSerde, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta}; #[test] fn create_default_grid_test() { @@ -64,6 +64,6 @@ mod tests { let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data); - let _: GridBlockMetaSerde = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); + let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 2d32fd1d9e..513a1ea9ec 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -212,7 +212,7 @@ impl GridMetaPad { } } - pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult> { + pub fn create_block_meta(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid| { if grid.block_metas.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); @@ -235,11 +235,11 @@ impl GridMetaPad { }) } - pub fn get_blocks(&self) -> Vec { + pub fn get_block_metas(&self) -> Vec { self.grid_meta.block_metas.clone() } - pub fn update_block(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { + pub fn update_block_meta(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; From ca45673a9ea159eb7ee97f1db984b594b9f2adfa Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 2 Apr 2022 21:17:20 +0800 Subject: [PATCH 085/179] chore: transform cell data --- .../src/services/block_meta_editor.rs | 3 +- .../type_options/checkbox_type_option.rs | 35 ++++- .../field/type_options/date_type_option.rs | 95 +++++++----- .../field/type_options/number_type_option.rs | 146 +++++++++++------- .../type_options/selection_type_option.rs | 48 +++++- .../field/type_options/text_type_option.rs | 82 +++++++++- .../field/type_options/type_option_data.rs | 6 +- .../flowy-grid/src/services/grid_editor.rs | 18 ++- .../src/services/row/cell_data_serde.rs | 67 +++++++- .../src/entities/meta.rs | 13 +- .../src/client_grid/grid_block_meta_pad.rs | 2 +- 11 files changed, 376 insertions(+), 139 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 58e8e2ca9e..353185f498 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -148,9 +148,10 @@ impl GridBlockMetaEditorManager { } // Optimization: Using the shared memory(Arc, Cow,etc.) to reduce memory usage. + #[allow(dead_code)] pub async fn get_cell_metas( &self, - block_ids: Option, + block_ids: Vec, field_id: &str, row_ids: Option>, ) -> FlowyResult> { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 3611f5a0db..84d693edd0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,11 +1,12 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::CellDataSerde; +use crate::services::row::{CellDataSerde, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; +use std::str::FromStr; #[derive(Default)] pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption); @@ -36,17 +37,30 @@ pub struct CheckboxTypeOption { } impl_type_option!(CheckboxTypeOption, FieldType::Checkbox); +const YES: &str = "Yes"; +const NO: &str = "No"; + impl CellDataSerde for CheckboxTypeOption { - fn deserialize_cell_data(&self, data: String) -> String { - data + fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { + if !type_option_cell_data.is_text() || !type_option_cell_data.is_checkbox() { + return String::new(); + } + let cell_data = type_option_cell_data.data; + if cell_data == YES || cell_data == NO { + return cell_data; + } + } + + String::new() } fn serialize_cell_data(&self, data: &str) -> Result { let s = match string_to_bool(data) { - true => "No", - false => "Yes", + true => YES, + false => NO, }; - Ok(s.to_owned()) + Ok(TypeOptionCellData::new(s, self.field_type()).json()) } } @@ -66,11 +80,15 @@ fn string_to_bool(bool_str: &str) -> bool { #[cfg(test)] mod tests { use crate::services::field::CheckboxTypeOption; + use crate::services::field::FieldBuilder; use crate::services::row::CellDataSerde; + use flowy_grid_data_model::entities::FieldType; #[test] fn checkout_box_description_test() { let type_option = CheckboxTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); + assert_eq!(type_option.serialize_cell_data("true").unwrap(), "1".to_owned()); assert_eq!(type_option.serialize_cell_data("1").unwrap(), "1".to_owned()); assert_eq!(type_option.serialize_cell_data("yes").unwrap(), "1".to_owned()); @@ -79,6 +97,9 @@ mod tests { assert_eq!(type_option.serialize_cell_data("no").unwrap(), "0".to_owned()); assert_eq!(type_option.serialize_cell_data("123").unwrap(), "0".to_owned()); - assert_eq!(type_option.deserialize_cell_data("1".to_owned()), "1".to_owned()); + assert_eq!( + type_option.deserialize_cell_data("1".to_owned(), &field_meta), + "1".to_owned() + ); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 86c15e13c5..5dd88a4a67 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,5 +1,5 @@ use crate::impl_type_option; -use crate::services::row::CellDataSerde; +use crate::services::row::{CellDataSerde, TypeOptionCellData}; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; @@ -7,6 +7,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; +use std::str::FromStr; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use strum_macros::EnumIter; @@ -32,25 +33,34 @@ impl DateTypeOption { 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 = format!("{} {}", self.date_format.format_str(), self.time_format.format_str()); - let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); + let output = format!("{}", local.format_with_items(StrftimeItems::new(&self.fmt_str()))); output } + + fn fmt_str(&self) -> String { + format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) + } } impl CellDataSerde for DateTypeOption { - fn deserialize_cell_data(&self, data: String) -> String { - match data.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) + fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { + if !type_option_cell_data.is_date() { + return String::new(); } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); - String::new() + + let cell_data = type_option_cell_data.data; + if let Ok(timestamp) = cell_data.parse::() { + let native = NaiveDateTime::from_timestamp(timestamp, 0); + return self.today_from_native(native); + } + + if NaiveDateTime::parse_from_str(&cell_data, &self.fmt_str()).is_ok() { + return cell_data; } } + + String::new() } fn serialize_cell_data(&self, data: &str) -> Result { @@ -58,7 +68,8 @@ impl CellDataSerde for DateTypeOption { tracing::error!("Parse {} to i64 failed: {}", data, e); return Err(FlowyError::internal().context(e)); }; - Ok(data.to_owned()) + + Ok(TypeOptionCellData::new(data, self.field_type()).json()) } } @@ -172,56 +183,59 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { + use crate::services::field::FieldBuilder; use crate::services::field::{DateFormat, DateTypeOption, TimeFormat}; - use crate::services::row::CellDataSerde; + use crate::services::row::{CellDataSerde, TypeOptionCellData}; + use flowy_grid_data_model::entities::FieldType; use strum::IntoEnumIterator; #[test] - fn date_description_date_format_test() { - let mut description = DateTypeOption::default(); - let _timestamp = 1647251762; + fn date_description_invalid_input_test() { + let type_option = DateTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + assert_eq!( + "".to_owned(), + type_option.deserialize_cell_data("1e".to_owned(), &field_meta) + ); + } + #[test] + fn date_description_date_format_test() { + let mut type_option = DateTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); for date_format in DateFormat::iter() { - description.date_format = date_format; + type_option.date_format = date_format; match date_format { DateFormat::Friendly => { assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.today_from_timestamp(1647251762) + type_option.deserialize_cell_data(data("1647251762"), &field_meta) ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.deserialize_cell_data("1647251762".to_owned()) + type_option.deserialize_cell_data(data("Mar 14,2022 17:56"), &field_meta) ); } DateFormat::US => { assert_eq!( "2022/03/14 17:56".to_owned(), - description.today_from_timestamp(1647251762) + type_option.deserialize_cell_data(data("1647251762"), &field_meta) ); assert_eq!( "2022/03/14 17:56".to_owned(), - description.deserialize_cell_data("1647251762".to_owned()) + type_option.deserialize_cell_data(data("2022/03/14 17:56"), &field_meta) ); } DateFormat::ISO => { assert_eq!( "2022-03-14 17:56".to_owned(), - description.today_from_timestamp(1647251762) - ); - assert_eq!( - "2022-03-14 17:56".to_owned(), - description.deserialize_cell_data("1647251762".to_owned()) + type_option.deserialize_cell_data(data("1647251762"), &field_meta) ); } DateFormat::Local => { assert_eq!( "2022/03/14 17:56".to_owned(), - description.today_from_timestamp(1647251762) - ); - assert_eq!( - "2022/03/14 17:56".to_owned(), - description.deserialize_cell_data("1647251762".to_owned()) + type_option.deserialize_cell_data(data("1647251762"), &field_meta) ); } } @@ -230,28 +244,29 @@ mod tests { #[test] fn date_description_time_format_test() { - let mut description = DateTypeOption::default(); + let mut type_option = DateTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); for time_format in TimeFormat::iter() { - description.time_format = time_format; + type_option.time_format = time_format; match time_format { TimeFormat::TwentyFourHour => { assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.today_from_timestamp(1647251762) + type_option.today_from_timestamp(1647251762) ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.deserialize_cell_data("1647251762".to_owned()) + type_option.deserialize_cell_data(data("1647251762"), &field_meta) ); } TimeFormat::TwelveHour => { assert_eq!( "Mar 14,2022 05:56:02 PM".to_owned(), - description.today_from_timestamp(1647251762) + type_option.today_from_timestamp(1647251762) ); assert_eq!( "Mar 14,2022 05:56:02 PM".to_owned(), - description.deserialize_cell_data("1647251762".to_owned()) + type_option.deserialize_cell_data(data("1647251762"), &field_meta) ); } } @@ -264,4 +279,8 @@ mod tests { let type_option = DateTypeOption::default(); type_option.serialize_cell_data("he").unwrap(); } + + fn data(s: &str) -> String { + TypeOptionCellData::new(s, FieldType::DateTime).json() + } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 7e557955df..7cee8a3b39 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; -use crate::services::row::CellDataSerde; +use crate::services::row::{CellDataSerde, TypeOptionCellData}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use lazy_static::lazy_static; -use rust_decimal::prelude::Zero; + use rust_decimal::Decimal; use rusty_money::iso::{Currency, CNY, EUR, USD}; use serde::{Deserialize, Serialize}; @@ -76,6 +76,42 @@ pub struct NumberTypeOption { } impl_type_option!(NumberTypeOption, FieldType::Number); +impl CellDataSerde for NumberTypeOption { + fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { + if type_option_cell_data.is_date() { + return String::new(); + } + + let cell_data = type_option_cell_data.data; + match self.format { + NumberFormat::Number => { + if cell_data.parse::().is_ok() { + cell_data + } else { + String::new() + } + } + NumberFormat::USD => self.money_from_str(&cell_data, USD), + NumberFormat::CNY => self.money_from_str(&cell_data, CNY), + NumberFormat::EUR => self.money_from_str(&cell_data, EUR), + } + } else { + String::new() + } + } + + fn serialize_cell_data(&self, data: &str) -> Result { + let data = self.strip_symbol(data); + + if !data.chars().all(char::is_numeric) { + return Err(FlowyError::invalid_data().context("Should only contain numbers")); + } + + Ok(TypeOptionCellData::new(&data, self.field_type()).json()) + } +} + impl std::default::Default for NumberTypeOption { fn default() -> Self { let format = NumberFormat::default(); @@ -96,22 +132,21 @@ impl NumberTypeOption { self.symbol = format.symbol(); } - fn decimal_from_str(&self, s: &str) -> Decimal { - let mut decimal = Decimal::from_str(s).unwrap_or_else(|_| Decimal::zero()); - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - decimal.set_sign_positive(self.sign_positive); - decimal - } - fn money_from_str(&self, s: &str, currency: &'static Currency) -> String { - let decimal = self.decimal_from_str(s); - let money = rusty_money::Money::from_decimal(decimal, currency); - money.to_string() + 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); + let money = rusty_money::Money::from_decimal(decimal, currency); + money.to_string() + } + Err(_) => String::new(), + } } fn strip_symbol(&self, s: &str) -> String { @@ -158,26 +193,6 @@ impl NumberFormat { } } -impl CellDataSerde for NumberTypeOption { - fn deserialize_cell_data(&self, data: String) -> String { - match self.format { - NumberFormat::Number => data, - NumberFormat::USD => self.money_from_str(&data, USD), - NumberFormat::CNY => self.money_from_str(&data, CNY), - NumberFormat::EUR => self.money_from_str(&data, EUR), - } - } - - fn serialize_cell_data(&self, data: &str) -> Result { - let data = self.strip_symbol(data); - - if !data.chars().all(char::is_numeric) { - return Err(FlowyError::invalid_data().context("Should only contain numbers")); - } - Ok(data) - } -} - fn make_strip_symbol() -> Vec { let mut symbols = vec![",".to_owned(), ".".to_owned()]; for format in NumberFormat::iter() { @@ -188,41 +203,60 @@ fn make_strip_symbol() -> Vec { #[cfg(test)] mod tests { + use crate::services::field::FieldBuilder; use crate::services::field::{NumberFormat, NumberTypeOption}; - use crate::services::row::CellDataSerde; + use crate::services::row::{CellDataSerde, TypeOptionCellData}; + use flowy_grid_data_model::entities::FieldType; use strum::IntoEnumIterator; + #[test] + fn number_description_invalid_input_test() { + let type_option = NumberTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + assert_eq!("".to_owned(), type_option.deserialize_cell_data(data(""), &field_meta)); + assert_eq!( + "".to_owned(), + type_option.deserialize_cell_data(data("abc"), &field_meta) + ); + } + #[test] fn number_description_test() { let mut type_option = NumberTypeOption::default(); - assert_eq!(type_option.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned()); - assert_eq!(type_option.serialize_cell_data("$18,443").unwrap(), "18443".to_owned()); - assert_eq!(type_option.serialize_cell_data("€18.443").unwrap(), "18443".to_owned()); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + assert_eq!(type_option.strip_symbol("¥18,443"), "18443".to_owned()); + assert_eq!(type_option.strip_symbol("$18,443"), "18443".to_owned()); + assert_eq!(type_option.strip_symbol("€18.443"), "18443".to_owned()); for format in NumberFormat::iter() { type_option.format = format; match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "$18,443".to_owned() ); + assert_eq!(type_option.deserialize_cell_data(data(""), &field_meta), "".to_owned()); + assert_eq!( + type_option.deserialize_cell_data(data("abc"), &field_meta), + "".to_owned() + ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "€18.443".to_owned() ); } @@ -230,37 +264,42 @@ mod tests { } } + fn data(s: &str) -> String { + TypeOptionCellData::new(s, FieldType::Number).json() + } + #[test] fn number_description_scale_test() { let mut type_option = NumberTypeOption { scale: 1, ..Default::default() }; + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); for format in NumberFormat::iter() { type_option.format = format; match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "$1,844.3".to_owned() ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "¥1,844.3".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "€1.844,3".to_owned() ); } @@ -274,31 +313,32 @@ mod tests { sign_positive: false, ..Default::default() }; + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); for format in NumberFormat::iter() { type_option.format = format; match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "-$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "-¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data("18443".to_owned()), + type_option.deserialize_cell_data(data("18443"), &field_meta), "-€18.443".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index abc9c81288..5768a92f70 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,6 +1,6 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::CellDataSerde; +use crate::services::row::{CellDataSerde, TypeOptionCellData}; use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; @@ -8,6 +8,7 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; +use std::str::FromStr; use uuid::Uuid; pub const SELECTION_IDS_SEPARATOR: &str = ","; @@ -24,12 +25,25 @@ pub struct SingleSelectTypeOption { impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); impl CellDataSerde for SingleSelectTypeOption { - fn deserialize_cell_data(&self, data: String) -> String { - data + fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { + if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { + return String::new(); + } + + let option_id = type_option_cell_data.data; + match self.options.iter().find(|option| option.id == option_id) { + None => String::new(), + Some(option) => option.name.clone(), + } + } else { + String::new() + } } fn serialize_cell_data(&self, data: &str) -> Result { - single_select_option_id_from_data(data.to_owned()) + let data = single_select_option_id_from_data(data.to_owned())?; + Ok(TypeOptionCellData::new(&data, self.field_type()).json()) } } @@ -67,12 +81,32 @@ pub struct MultiSelectTypeOption { impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); impl CellDataSerde for MultiSelectTypeOption { - fn deserialize_cell_data(&self, data: String) -> String { - data + fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { + if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { + return String::new(); + } + + match select_option_ids(type_option_cell_data.data) { + Ok(option_ids) => { + // + self.options + .iter() + .filter(|option| option_ids.contains(&option.id)) + .map(|option| option.name.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR) + } + Err(_) => String::new(), + } + } else { + String::new() + } } fn serialize_cell_data(&self, data: &str) -> Result { - multi_select_option_id_from_data(data.to_owned()) + let data = multi_select_option_id_from_data(data.to_owned())?; + Ok(TypeOptionCellData::new(&data, self.field_type()).json()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 6bffc8606f..87434a3cdb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,11 +1,12 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::CellDataSerde; +use crate::services::row::{deserialize_cell_data, CellDataSerde, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; +use std::str::FromStr; #[derive(Default)] pub struct RichTextTypeOptionBuilder(RichTextTypeOption); @@ -30,8 +31,20 @@ pub struct RichTextTypeOption { impl_type_option!(RichTextTypeOption, FieldType::RichText); impl CellDataSerde for RichTextTypeOption { - fn deserialize_cell_data(&self, data: String) -> String { - data + fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { + if type_option_cell_data.is_date() + || type_option_cell_data.is_single_select() + || type_option_cell_data.is_multi_select() + || type_option_cell_data.is_number() + { + deserialize_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned()) + } else { + type_option_cell_data.data + } + } else { + String::new() + } } fn serialize_cell_data(&self, data: &str) -> Result { @@ -39,7 +52,68 @@ impl CellDataSerde for RichTextTypeOption { if data.len() > 10000 { Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) } else { - Ok(data) + Ok(TypeOptionCellData::new(&data, self.field_type()).json()) } } } + +#[cfg(test)] +mod tests { + use crate::services::field::FieldBuilder; + use crate::services::field::*; + use crate::services::row::{CellDataSerde, TypeOptionCellData}; + use flowy_grid_data_model::entities::FieldType; + + #[test] + fn text_description_test() { + let type_option = RichTextTypeOption::default(); + + // date + let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); + let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); + assert_eq!( + type_option.deserialize_cell_data(data, &date_time_field_meta), + "Mar 14,2022 17:56".to_owned() + ); + + // Single select + let done_option = SelectOption::new("Done"); + let done_option_id = done_option.id.clone(); + let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); + let single_select_field_meta = FieldBuilder::new(single_select).build(); + let data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); + assert_eq!( + type_option.deserialize_cell_data(data, &single_select_field_meta), + "Done".to_owned() + ); + + // Multiple select + let google_option = SelectOption::new("Google"); + let google_option_id = google_option.id.clone(); + let facebook_option = SelectOption::new("Facebook"); + let face_option_id = facebook_option.id.clone(); + let multi_select = MultiSelectTypeOptionBuilder::default() + .option(google_option) + .option(facebook_option) + .option(SelectOption::new("Twitter")); + let multi_select_field_meta = FieldBuilder::new(multi_select).build(); + let data = TypeOptionCellData::new( + &vec![google_option_id, face_option_id].join(SELECTION_IDS_SEPARATOR), + FieldType::SingleSelect, + ) + .json(); + assert_eq!( + type_option.deserialize_cell_data(data, &multi_select_field_meta), + "Google,Facebook".to_owned() + ); + + //Number + let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD); + let number_field_meta = FieldBuilder::new(number).build(); + let data = TypeOptionCellData::new("18443", FieldType::Number).json(); + assert_eq!( + type_option.deserialize_cell_data(data, &number_field_meta), + "$18,443".to_owned() + ); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs index fbba14feab..8b13789179 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs @@ -1,5 +1 @@ -// #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] -// pub struct TypeOptionData { -// #[pb(index = 1)] -// pub map: HashMap, -// } + 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 88738aa082..e7d57634b8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -114,7 +114,16 @@ impl ClientGridEditor { } pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> { - // let cell_metas = self.block_meta_manager.get_cell_metas(None, field_id, None).await?; + // let block_ids = self + // .get_block_metas() + // .await? + // .into_iter() + // .map(|block_meta| block_meta.block_id) + // .collect(); + // let cell_metas = self + // .block_meta_manager + // .get_cell_metas(block_ids, field_id, None) + // .await?; let type_option_json_builder = |field_type: &FieldType| -> String { return default_type_option_builder_from_type(field_type).entry().json_str(); @@ -290,15 +299,16 @@ impl ClientGridEditor { } pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { - let block_ids = block_ids.unwrap_or( - self.pad + let block_ids = match block_ids { + None => self.pad .read() .await .get_block_metas() .into_iter() .map(|block_meta| block_meta.block_id) .collect::>(), - ); + Some(block_ids) => block_ids, + }; let snapshots = self.block_meta_manager.make_block_snapshots(block_ids).await?; Ok(snapshots) } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs index 1e60583df8..259e052ab7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs @@ -1,12 +1,65 @@ use crate::services::field::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use serde::{Deserialize, Serialize}; pub trait CellDataSerde { - fn deserialize_cell_data(&self, data: String) -> String; + fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; fn serialize_cell_data(&self, data: &str) -> Result; } +#[derive(Serialize, Deserialize)] +pub struct TypeOptionCellData { + pub data: String, + pub field_type: FieldType, +} + +impl std::str::FromStr for TypeOptionCellData { + type Err = FlowyError; + + fn from_str(s: &str) -> Result { + let type_option_cell_data: TypeOptionCellData = serde_json::from_str(s)?; + Ok(type_option_cell_data) + } +} + +impl TypeOptionCellData { + pub fn new(data: &str, field_type: FieldType) -> Self { + TypeOptionCellData { + data: data.to_owned(), + field_type, + } + } + + pub fn json(&self) -> String { + serde_json::to_string(self).unwrap_or_else(|_| "".to_owned()) + } + + pub fn is_number(&self) -> bool { + self.field_type == FieldType::Number + } + + pub fn is_text(&self) -> bool { + self.field_type == FieldType::RichText + } + + pub fn is_checkbox(&self) -> bool { + self.field_type == FieldType::Checkbox + } + + pub fn is_date(&self) -> bool { + self.field_type == FieldType::DateTime + } + + pub fn is_single_select(&self) -> bool { + self.field_type == FieldType::SingleSelect + } + + pub fn is_multi_select(&self) -> bool { + self.field_type == FieldType::MultiSelect + } +} + #[allow(dead_code)] pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result { match field_meta.field_type { @@ -21,12 +74,12 @@ pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result Result { let s = match field_meta.field_type { - FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data), - FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data), - FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data), - FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data), - FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data), - FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data), + FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), }; Ok(s) } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index edb5236139..a543085a78 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -246,6 +246,7 @@ impl TryInto for FieldChangesetPayload { #[derive( Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize, )] +#[repr(u8)] pub enum FieldType { RichText = 0, Number = 1, @@ -278,18 +279,6 @@ impl FieldType { let ty = self.clone(); format!("{}", ty as u8) } - - pub fn from_type_id(type_id: &str) -> Result { - match type_id { - "0" => Ok(FieldType::RichText), - "1" => Ok(FieldType::Number), - "2" => Ok(FieldType::DateTime), - "3" => Ok(FieldType::SingleSelect), - "4" => Ok(FieldType::MultiSelect), - "5" => Ok(FieldType::Checkbox), - _ => Err(format!("Invalid type_id: {}", type_id)), - } - } } #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 0b9459a625..c0b86ac4af 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -5,7 +5,7 @@ use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowM use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; + use std::collections::HashMap; use std::sync::Arc; From 6ac2617113c15311245e5df730c3528e129493d2 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 2 Apr 2022 23:48:56 +0800 Subject: [PATCH 086/179] chore: update row state using provider --- .../application/grid/row/row_bloc.dart | 10 --- .../grid/src/widgets/content/grid_row.dart | 65 ++++++++++++------- .../flowy-grid/src/services/grid_editor.rs | 8 ++- .../src/client_grid/grid_block_meta_pad.rs | 3 +- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index ac99eac67b..6fc7221a76 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -41,12 +41,6 @@ class RowBloc extends Bloc { createRow: (_CreateRow value) { rowService.createRow(); }, - activeRow: (_ActiveRow value) { - emit(state.copyWith(active: true)); - }, - disactiveRow: (_DisactiveRow value) { - emit(state.copyWith(active: false)); - }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(fields: value.fields)); add(const RowEvent.didUpdateCell()); @@ -133,8 +127,6 @@ class RowBloc extends Bloc { class RowEvent with _$RowEvent { const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; - const factory RowEvent.activeRow() = _ActiveRow; - const factory RowEvent.disactiveRow() = _DisactiveRow; const factory RowEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; const factory RowEvent.didUpdateCell() = _DidUpdateCell; } @@ -143,7 +135,6 @@ class RowEvent with _$RowEvent { class RowState with _$RowState { const factory RowState({ required String rowId, - required bool active, required double rowHeight, required List fields, required Future> row, @@ -152,7 +143,6 @@ class RowState with _$RowState { factory RowState.initial(GridRowData data) => RowState( rowId: data.rowId, - active: false, rowHeight: data.height, fields: data.fields, row: Future(() => none()), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index b8834cd213..23918401c4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -6,6 +6,7 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; @@ -19,10 +20,12 @@ class GridRowWidget extends StatefulWidget { class _GridRowWidgetState extends State { late RowBloc _rowBloc; + late RowRegionStateNotifier _rowStateNotifier; @override void initState() { _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); + _rowStateNotifier = RowRegionStateNotifier(); super.initState(); } @@ -30,25 +33,28 @@ class _GridRowWidgetState extends State { Widget build(BuildContext context) { return BlocProvider.value( value: _rowBloc, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), - onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, + child: ChangeNotifierProvider.value( + value: _rowStateNotifier, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowStateNotifier.onEnter = true, + onExit: (p) => _rowStateNotifier.onEnter = false, + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, + ), ), ), ); @@ -57,6 +63,7 @@ class _GridRowWidgetState extends State { @override Future dispose() async { _rowBloc.close(); + _rowStateNotifier.dispose(); super.dispose(); } } @@ -66,10 +73,9 @@ class _RowLeading extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocSelector( - selector: (state) => state.active, - builder: (context, isActive) { - return SizedBox(width: GridSize.leadingHeaderPadding, child: isActive ? _activeWidget() : null); + return Consumer( + builder: (context, state, _) { + return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null); }, ); } @@ -133,3 +139,16 @@ class _RowCells extends StatelessWidget { ); } } + +class RowRegionStateNotifier extends ChangeNotifier { + bool _onEnter = false; + + set onEnter(bool value) { + if (_onEnter != value) { + _onEnter = value; + notifyListeners(); + } + } + + bool get onEnter => _onEnter; +} 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 e7d57634b8..3925f80b24 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -233,7 +233,7 @@ impl ClientGridEditor { } } - pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + pub async fn update_cell(&self, mut changeset: CellMetaChangeset) -> FlowyResult<()> { if let Some(cell_data) = changeset.data.as_ref() { match self.pad.read().await.get_field(&changeset.field_id) { None => { @@ -241,7 +241,8 @@ impl ClientGridEditor { .context(format!("Can not find the field with id: {}", &changeset.field_id))); } Some(field_meta) => { - let _ = serialize_cell_data(cell_data, field_meta)?; + let cell_data = serialize_cell_data(cell_data, field_meta)?; + changeset.data = Some(cell_data); } } } @@ -300,7 +301,8 @@ impl ClientGridEditor { pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { let block_ids = match block_ids { - None => self.pad + None => self + .pad .read() .await .get_block_metas() diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index c0b86ac4af..688b32cccc 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -24,8 +24,7 @@ pub struct GridBlockMetaPad { impl GridBlockMetaPad { pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - tracing::info!("delta: {}", delta); - tracing::info!("{}", s); + tracing::trace!("{}", s); let meta_data: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { let msg = format!("Deserialize delta to block meta failed: {}", e); CollaborateError::internal().context(msg) From 147e948b350e6f89b7bd7831618f1be1184b7c4f Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 2 Apr 2022 23:54:48 +0800 Subject: [PATCH 087/179] chore: add grid setting --- .../grid/src/widgets/header/grid_setting.dart | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart new file mode 100644 index 0000000000..dff1058c52 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart @@ -0,0 +1,35 @@ +enum GridSetting { + filter, + sortBy, + properties, +} + +extension _GridSettingExtension on GridSetting { + String iconName() { + switch (this) { + case GridSetting.filter: + // TODO: Handle this case. + break; + case GridSetting.sortBy: + // TODO: Handle this case. + break; + case GridSetting.properties: + // TODO: Handle this case. + break; + } + } + + String title() { + switch (this) { + case GridSetting.filter: + // TODO: Handle this case. + break; + case GridSetting.sortBy: + // TODO: Handle this case. + break; + case GridSetting.properties: + // TODO: Handle this case. + break; + } + } +} From 79c178a6e194a1c1bb17bb6669e00fd6b23bad7e Mon Sep 17 00:00:00 2001 From: MrTanoshii <47116127+MrTanoshii@users.noreply.github.com> Date: Sat, 2 Apr 2022 21:18:18 +0400 Subject: [PATCH 088/179] docs: make `'` regular text --- shared-lib/flowy-sync/src/READ_ME.json | 2 +- shared-lib/flowy-sync/src/client_document/default/READ_ME.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-lib/flowy-sync/src/READ_ME.json b/shared-lib/flowy-sync/src/READ_ME.json index bb53eff10e..624802720c 100644 --- a/shared-lib/flowy-sync/src/READ_ME.json +++ b/shared-lib/flowy-sync/src/READ_ME.json @@ -1 +1 @@ -[{"insert":"\n👋 Welcome to AppFlowy!"},{"insert":"\n","attributes":{"header":1}},{"insert":"\nHere are the basics"},{"insert":"\n","attributes":{"header":2}},{"insert":"Click anywhere and just start typing"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Highlight","attributes":{"background":"#fff2cd"}},{"insert":" any text, and use the menu at the bottom to "},{"insert":"style","attributes":{"italic":true}},{"insert":" "},{"insert":"your","attributes":{"bold":true}},{"insert":" "},{"insert":"writing","attributes":{"underline":true}},{"insert":" "},{"insert":"however","attributes":{"code":true}},{"insert":" "},{"insert":"you","attributes":{"strike":true}},{"insert":" "},{"insert":"like","attributes":{"background":"#e8e0ff"}},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click "},{"insert":"+ New Page","attributes":{"background":"#defff1","bold":true}},{"insert":" button at the bottom of your sidebar to add a new page"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click the "},{"insert":"'","attributes":{"background":"#defff1"}},{"insert":"+'","attributes":{"background":"#defff1","bold":true}},{"insert":" next to any page title in the sidebar to quickly add a new subpage"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\nHave a question? "},{"insert":"\n","attributes":{"header":2}},{"insert":"Click the "},{"insert":"'?'","attributes":{"background":"#defff1","bold":true}},{"insert":" at the bottom right for help and support.\n\nLike AppFlowy? Follow us:"},{"insert":"\n","attributes":{"header":2}},{"insert":"GitHub: https://github.com/AppFlowy-IO/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Twitter: https://twitter.com/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Newsletter: https://www.appflowy.io/blog"},{"insert":"\n","attributes":{"blockquote":true}}] \ No newline at end of file +[{"insert":"\n👋 Welcome to AppFlowy!"},{"insert":"\n","attributes":{"header":1}},{"insert":"\nHere are the basics"},{"insert":"\n","attributes":{"header":2}},{"insert":"Click anywhere and just start typing"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Highlight","attributes":{"background":"#fff2cd"}},{"insert":" any text, and use the menu at the bottom to "},{"insert":"style","attributes":{"italic":true}},{"insert":" "},{"insert":"your","attributes":{"bold":true}},{"insert":" "},{"insert":"writing","attributes":{"underline":true}},{"insert":" "},{"insert":"however","attributes":{"code":true}},{"insert":" "},{"insert":"you","attributes":{"strike":true}},{"insert":" "},{"insert":"like","attributes":{"background":"#e8e0ff"}},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click "},{"insert":"+ New Page","attributes":{"background":"#defff1","bold":true}},{"insert":" button at the bottom of your sidebar to add a new page"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click the "},{"insert":"'","attributes":{"background":"#defff1"}},{"insert":"+","attributes":{"background":"#defff1","bold":true}},{"insert":"'","attributes":{"background":"#defff1"}},{"insert":" next to any page title in the sidebar to quickly add a new subpage"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\nHave a question? "},{"insert":"\n","attributes":{"header":2}},{"insert":"Click the "},{"insert":"'?'","attributes":{"background":"#defff1","bold":true}},{"insert":" at the bottom right for help and support.\n\nLike AppFlowy? Follow us:"},{"insert":"\n","attributes":{"header":2}},{"insert":"GitHub: https://github.com/AppFlowy-IO/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Twitter: https://twitter.com/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Newsletter: https://www.appflowy.io/blog"},{"insert":"\n","attributes":{"blockquote":true}}] \ No newline at end of file diff --git a/shared-lib/flowy-sync/src/client_document/default/READ_ME.json b/shared-lib/flowy-sync/src/client_document/default/READ_ME.json index bb53eff10e..624802720c 100644 --- a/shared-lib/flowy-sync/src/client_document/default/READ_ME.json +++ b/shared-lib/flowy-sync/src/client_document/default/READ_ME.json @@ -1 +1 @@ -[{"insert":"\n👋 Welcome to AppFlowy!"},{"insert":"\n","attributes":{"header":1}},{"insert":"\nHere are the basics"},{"insert":"\n","attributes":{"header":2}},{"insert":"Click anywhere and just start typing"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Highlight","attributes":{"background":"#fff2cd"}},{"insert":" any text, and use the menu at the bottom to "},{"insert":"style","attributes":{"italic":true}},{"insert":" "},{"insert":"your","attributes":{"bold":true}},{"insert":" "},{"insert":"writing","attributes":{"underline":true}},{"insert":" "},{"insert":"however","attributes":{"code":true}},{"insert":" "},{"insert":"you","attributes":{"strike":true}},{"insert":" "},{"insert":"like","attributes":{"background":"#e8e0ff"}},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click "},{"insert":"+ New Page","attributes":{"background":"#defff1","bold":true}},{"insert":" button at the bottom of your sidebar to add a new page"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click the "},{"insert":"'","attributes":{"background":"#defff1"}},{"insert":"+'","attributes":{"background":"#defff1","bold":true}},{"insert":" next to any page title in the sidebar to quickly add a new subpage"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\nHave a question? "},{"insert":"\n","attributes":{"header":2}},{"insert":"Click the "},{"insert":"'?'","attributes":{"background":"#defff1","bold":true}},{"insert":" at the bottom right for help and support.\n\nLike AppFlowy? Follow us:"},{"insert":"\n","attributes":{"header":2}},{"insert":"GitHub: https://github.com/AppFlowy-IO/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Twitter: https://twitter.com/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Newsletter: https://www.appflowy.io/blog"},{"insert":"\n","attributes":{"blockquote":true}}] \ No newline at end of file +[{"insert":"\n👋 Welcome to AppFlowy!"},{"insert":"\n","attributes":{"header":1}},{"insert":"\nHere are the basics"},{"insert":"\n","attributes":{"header":2}},{"insert":"Click anywhere and just start typing"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Highlight","attributes":{"background":"#fff2cd"}},{"insert":" any text, and use the menu at the bottom to "},{"insert":"style","attributes":{"italic":true}},{"insert":" "},{"insert":"your","attributes":{"bold":true}},{"insert":" "},{"insert":"writing","attributes":{"underline":true}},{"insert":" "},{"insert":"however","attributes":{"code":true}},{"insert":" "},{"insert":"you","attributes":{"strike":true}},{"insert":" "},{"insert":"like","attributes":{"background":"#e8e0ff"}},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click "},{"insert":"+ New Page","attributes":{"background":"#defff1","bold":true}},{"insert":" button at the bottom of your sidebar to add a new page"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Click the "},{"insert":"'","attributes":{"background":"#defff1"}},{"insert":"+","attributes":{"background":"#defff1","bold":true}},{"insert":"'","attributes":{"background":"#defff1"}},{"insert":" next to any page title in the sidebar to quickly add a new subpage"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\nHave a question? "},{"insert":"\n","attributes":{"header":2}},{"insert":"Click the "},{"insert":"'?'","attributes":{"background":"#defff1","bold":true}},{"insert":" at the bottom right for help and support.\n\nLike AppFlowy? Follow us:"},{"insert":"\n","attributes":{"header":2}},{"insert":"GitHub: https://github.com/AppFlowy-IO/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Twitter: https://twitter.com/appflowy"},{"insert":"\n","attributes":{"blockquote":true}},{"insert":"Newsletter: https://www.appflowy.io/blog"},{"insert":"\n","attributes":{"blockquote":true}}] \ No newline at end of file From 5d007c53598a5965549d76246539ebc10e55b79e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 3 Apr 2022 10:53:24 +0800 Subject: [PATCH 089/179] chore: grid setting list --- .../assets/images/editor/Icons 16/Yen.svg | 3 - .../setting/ascending.svg} | 0 .../setting/descending.svg} | 0 .../Filter.svg => grid/setting/filter.svg} | 0 .../setting/properties.svg} | 0 .../assets/images/grid/setting/setting.svg | 4 + .../assets/images/grid/setting/sort.svg | 4 + .../app_flowy/assets/translations/en.json | 5 + .../lib/user/presentation/sign_in_screen.dart | 4 +- .../lib/user/presentation/sign_up_screen.dart | 8 +- .../user/presentation/widgets/background.dart | 2 +- .../workspace/application/grid/prelude.dart | 3 + .../grid/setting/setting_bloc.dart | 47 ++++++ .../workspace/application/view/view_ext.dart | 2 +- .../home/menu/app/header/add_button.dart | 2 +- .../home/menu/app/header/header.dart | 4 +- .../menu/app/section/disclosure_action.dart | 2 +- .../home/menu/app/section/item.dart | 8 +- .../presentation/home/menu/menu.dart | 2 +- .../presentation/home/menu/menu_user.dart | 2 +- .../presentation/home/navigation.dart | 2 +- .../plugins/doc/src/widget/style_widgets.dart | 2 +- .../doc/src/widget/toolbar/link_button.dart | 4 +- .../widget/toolbar/toolbar_icon_button.dart | 2 +- .../plugins/grid/src/grid_page.dart | 2 + .../grid/src/widgets/content/grid_row.dart | 2 +- .../grid/src/widgets/footer/grid_footer.dart | 2 +- .../grid/src/widgets/header/field_list.dart | 13 +- .../widgets/header/field_operation_list.dart | 8 +- .../src/widgets/header/field_switcher.dart | 4 +- .../header/grid_field_action_sheet.dart | 14 +- .../src/widgets/header/grid_field_editor.dart | 6 +- .../grid/src/widgets/header/grid_header.dart | 2 +- .../src/widgets/header/grid_header_cell.dart | 17 +- .../grid/src/widgets/header/grid_setting.dart | 35 ---- .../src/widgets/header/type_option/date.dart | 8 +- .../type_option/edit_option_pannel.dart | 16 +- .../widgets/header/type_option/number.dart | 16 +- .../header/type_option/option_pannel.dart | 20 +-- .../src/widgets/toolbar/grid_property.dart | 19 +++ .../src/widgets/toolbar/grid_setting.dart | 152 ++++++++++++++++++ .../src/widgets/toolbar/grid_toolbar.dart | 44 +++++ .../presentation/plugins/trash/menu.dart | 2 +- .../plugins/trash/src/trash_cell.dart | 4 +- .../presentation/plugins/trash/trash.dart | 4 +- .../packages/flowy_infra/lib/image.dart | 4 +- .../lib/style_widget/button.dart | 3 + .../lib/style_widget/hover.dart | 9 +- .../lib/style_widget/icon_button.dart | 2 +- frontend/app_flowy/pubspec.yaml | 1 + 50 files changed, 384 insertions(+), 137 deletions(-) delete mode 100644 frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg rename frontend/app_flowy/assets/images/{editor/Icons 16/Sort/Ascending.svg => grid/setting/ascending.svg} (100%) rename frontend/app_flowy/assets/images/{editor/Icons 16/Sort/Descending.svg => grid/setting/descending.svg} (100%) rename frontend/app_flowy/assets/images/{editor/Icons 16/Filter.svg => grid/setting/filter.svg} (100%) rename frontend/app_flowy/assets/images/{editor/Icons 16/Properties.svg => grid/setting/properties.svg} (100%) create mode 100644 frontend/app_flowy/assets/images/grid/setting/setting.svg create mode 100644 frontend/app_flowy/assets/images/grid/setting/sort.svg create mode 100644 frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart delete mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg b/frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg deleted file mode 100644 index b7cf1d361d..0000000000 --- a/frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Sort/Ascending.svg b/frontend/app_flowy/assets/images/grid/setting/ascending.svg similarity index 100% rename from frontend/app_flowy/assets/images/editor/Icons 16/Sort/Ascending.svg rename to frontend/app_flowy/assets/images/grid/setting/ascending.svg diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Sort/Descending.svg b/frontend/app_flowy/assets/images/grid/setting/descending.svg similarity index 100% rename from frontend/app_flowy/assets/images/editor/Icons 16/Sort/Descending.svg rename to frontend/app_flowy/assets/images/grid/setting/descending.svg diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Filter.svg b/frontend/app_flowy/assets/images/grid/setting/filter.svg similarity index 100% rename from frontend/app_flowy/assets/images/editor/Icons 16/Filter.svg rename to frontend/app_flowy/assets/images/grid/setting/filter.svg diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Properties.svg b/frontend/app_flowy/assets/images/grid/setting/properties.svg similarity index 100% rename from frontend/app_flowy/assets/images/editor/Icons 16/Properties.svg rename to frontend/app_flowy/assets/images/grid/setting/properties.svg diff --git a/frontend/app_flowy/assets/images/grid/setting/setting.svg b/frontend/app_flowy/assets/images/grid/setting/setting.svg new file mode 100644 index 0000000000..3d632703ab --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/setting/setting.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/setting/sort.svg b/frontend/app_flowy/assets/images/grid/setting/sort.svg new file mode 100644 index 0000000000..06e17d62a9 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/setting/sort.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index b9ab426fbd..9d73711cc7 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -143,6 +143,11 @@ } }, "grid": { + "settings": { + "filter": "Filter", + "sortBy": "Sort by", + "Properties": "Properties" + }, "field": { "hide": "Hide", "insertLeft": "Insert Left", diff --git a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart index 8124241cf4..9a02863345 100644 --- a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart @@ -170,8 +170,8 @@ class PasswordTextField extends StatelessWidget { return RoundedInputField( obscureText: true, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - obscureIcon: svg("home/hide"), - obscureHideIcon: svg("home/show"), + obscureIcon: svgWidget("home/hide"), + obscureHideIcon: svgWidget("home/show"), hintText: LocaleKeys.signIn_passwordHint.tr(), normalBorderColor: theme.shader4, errorBorderColor: theme.red, diff --git a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart index 06d4db6da2..9f95a1db75 100644 --- a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart @@ -134,8 +134,8 @@ class PasswordTextField extends StatelessWidget { builder: (context, state) { return RoundedInputField( obscureText: true, - obscureIcon: svg("home/hide"), - obscureHideIcon: svg("home/show"), + obscureIcon: svgWidget("home/hide"), + obscureHideIcon: svgWidget("home/show"), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), hintText: LocaleKeys.signUp_passwordHint.tr(), normalBorderColor: theme.shader4, @@ -162,8 +162,8 @@ class RepeatPasswordTextField extends StatelessWidget { builder: (context, state) { return RoundedInputField( obscureText: true, - obscureIcon: svg("home/hide"), - obscureHideIcon: svg("home/show"), + obscureIcon: svgWidget("home/hide"), + obscureHideIcon: svgWidget("home/show"), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), hintText: LocaleKeys.signUp_repeatPasswordHint.tr(), normalBorderColor: theme.shader4, diff --git a/frontend/app_flowy/lib/user/presentation/widgets/background.dart b/frontend/app_flowy/lib/user/presentation/widgets/background.dart index 86dfab7ffe..225f7f0080 100644 --- a/frontend/app_flowy/lib/user/presentation/widgets/background.dart +++ b/frontend/app_flowy/lib/user/presentation/widgets/background.dart @@ -44,7 +44,7 @@ class FlowyLogoTitle extends StatelessWidget { children: [ SizedBox.fromSize( size: logoSize, - child: svg("flowy_logo"), + child: svgWidget("flowy_logo"), ), const VSpace(30), Text( diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 8b13a4f34d..6c766ee218 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -23,3 +23,6 @@ export 'cell_bloc/selection_cell_bloc.dart'; export 'cell_bloc/date_cell_bloc.dart'; export 'cell_bloc/checkbox_cell_bloc.dart'; export 'cell_bloc/cell_service.dart'; + +// Setting +export 'setting/setting_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart new file mode 100644 index 0000000000..38071155af --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart @@ -0,0 +1,47 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'setting_bloc.freezed.dart'; + +class GridSettingBloc extends Bloc { + final String gridId; + GridSettingBloc({required this.gridId}) : super(GridSettingState.initial()) { + on( + (event, emit) async { + event.map(performAction: (_PerformAction value) { + emit(state.copyWith(selectedAction: Some(value.action))); + }); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class GridSettingEvent with _$GridSettingEvent { + const factory GridSettingEvent.performAction(GridSettingAction action) = _PerformAction; +} + +@freezed +class GridSettingState with _$GridSettingState { + const factory GridSettingState({ + required Option selectedAction, + }) = _GridSettingState; + + factory GridSettingState.initial() => GridSettingState( + selectedAction: none(), + ); +} + +enum GridSettingAction { + filter, + sortBy, + properties, +} diff --git a/frontend/app_flowy/lib/workspace/application/view/view_ext.dart b/frontend/app_flowy/lib/workspace/application/view/view_ext.dart index cf80a820a0..78230e1311 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_ext.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_ext.dart @@ -39,7 +39,7 @@ extension ViewExtension on View { thumbnail = "file_icon"; } - final Widget widget = svg(thumbnail, color: iconColor); + final Widget widget = svgWidget(thumbnail, color: iconColor); return widget; } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart index 9e696e8a73..6df78a67cc 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart @@ -28,7 +28,7 @@ class AddButton extends StatelessWidget { onSelected: onSelected, ).show(context); }, - icon: svg("home/add").padding(horizontal: 3, vertical: 3), + icon: svgWidget("home/add").padding(horizontal: 3, vertical: 3), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart index b773814f2d..ff1d6e6822 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart @@ -153,9 +153,9 @@ extension AppDisclosureExtension on AppDisclosureAction { Widget get icon { switch (this) { case AppDisclosureAction.rename: - return svg('editor/edit', color: const Color(0xffe5e5e5)); + return svgWidget('editor/edit', color: const Color(0xffe5e5e5)); case AppDisclosureAction.delete: - return svg('editor/delete', color: const Color(0xffe5e5e5)); + return svgWidget('editor/delete', color: const Color(0xffe5e5e5)); } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart index a706ae5019..c9a02a9de7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart @@ -32,7 +32,7 @@ class ViewDisclosureButton extends StatelessWidget with ActionList _render(context, onHover, state, theme.iconColor), - isOnSelected: () => state.isEditing || isSelected, + setSelected: () => state.isEditing || isSelected, ), ); }, @@ -126,11 +126,11 @@ extension ViewDisclosureExtension on ViewDisclosureAction { Widget get icon { switch (this) { case ViewDisclosureAction.rename: - return svg('editor/edit', color: const Color(0xff999999)); + return svgWidget('editor/edit', color: const Color(0xff999999)); case ViewDisclosureAction.delete: - return svg('editor/delete', color: const Color(0xff999999)); + return svgWidget('editor/delete', color: const Color(0xff999999)); case ViewDisclosureAction.duplicate: - return svg('editor/copy', color: const Color(0xff999999)); + return svgWidget('editor/copy', color: const Color(0xff999999)); } } } 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 73771596cb..395a85bf45 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart @@ -186,7 +186,7 @@ class MenuTopBar extends StatelessWidget { width: 28, onPressed: () => context.read().add(const MenuEvent.collapse()), iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), - icon: svg("home/hide_menu", color: theme.iconColor), + icon: svgWidget("home/hide_menu", color: theme.iconColor), ) ], ), diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart index fb0a4284d8..3a1674e486 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart @@ -80,7 +80,7 @@ class MenuUser extends StatelessWidget { }, icon: SizedBox.square( dimension: 20, - child: svg("home/settings", color: theme.iconColor), + child: svgWidget("home/settings", color: theme.iconColor), ), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart b/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart index 511b94db90..b6947c79fe 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart @@ -97,7 +97,7 @@ class FlowyNavigation extends StatelessWidget { notifier.value = false; }, iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), - icon: svg("home/hide_menu", color: theme.iconColor), + icon: svgWidget("home/hide_menu", color: theme.iconColor), ), ); } else { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/style_widgets.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/style_widgets.dart index 9d307b3ace..4f09b64053 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/style_widgets.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/style_widgets.dart @@ -51,7 +51,7 @@ class _FlowyEditorCheckboxState extends State { @override Widget build(BuildContext context) { - final icon = isChecked ? svg('editor/editor_check') : svg('editor/editor_uncheck'); + final icon = isChecked ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck'); return Align( alignment: Alignment.centerLeft, child: FlowyIconButton( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/link_button.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/link_button.dart index 3daa9f0679..60b654302f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/link_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/link_button.dart @@ -54,11 +54,11 @@ class _FlowyLinkStyleButtonState extends State { final isEnabled = !widget.controller.selection.isCollapsed; final pressedHandler = isEnabled ? () => _openLinkDialog(context) : null; final icon = isEnabled - ? svg( + ? svgWidget( 'editor/share', color: theme.iconColor, ) - : svg( + : svgWidget( 'editor/share', color: theme.disableIconColor, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/toolbar_icon_button.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/toolbar_icon_button.dart index 500f683355..b6dddefbb3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/toolbar_icon_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/toolbar_icon_button.dart @@ -29,7 +29,7 @@ class ToolbarIconButton extends StatelessWidget { iconPadding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4), onPressed: onPressed, width: width, - icon: isToggled == true ? svg(iconName, color: Colors.white) : svg(iconName), + icon: isToggled == true ? svgWidget(iconName, color: Colors.white) : svgWidget(iconName), fillColor: isToggled == true ? theme.main1 : theme.shader6, hoverColor: isToggled == true ? theme.main1 : theme.shader5, tooltipText: tooltipText, 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 984ed147a1..1a8b5f4036 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 @@ -13,6 +13,7 @@ import 'layout/sizes.dart'; import 'widgets/content/grid_row.dart'; import 'widgets/footer/grid_footer.dart'; import 'widgets/header/grid_header.dart'; +import 'widgets/toolbar/grid_toolbar.dart'; class GridPage extends StatefulWidget { final View view; @@ -99,6 +100,7 @@ class _FlowyGridState extends State { physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ + SliverToBoxAdapter(child: GridToolbar(gridId: gridId)), _buildHeader(gridId), _buildRows(context), const GridFooter(), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 23918401c4..53c27d62b4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -110,7 +110,7 @@ class AppendRowButton extends StatelessWidget { width: 22, onPressed: () => context.read().add(const RowEvent.createRow()), iconPadding: const EdgeInsets.all(3), - icon: svg("home/add"), + icon: svgWidget("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 7528c3c00a..8d9719ae75 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -39,7 +39,7 @@ class _AddRowButton extends StatelessWidget { text: const FlowyText.medium('New row', fontSize: 12), hoverColor: theme.hover, onTap: () => context.read().add(const GridEvent.createRow()), - leftIcon: svg("home/add"), + leftIcon: svgWidget("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart index 4511a84a1f..b83ad267f9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -13,14 +14,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; typedef SelectFieldCallback = void Function(FieldType); -class FieldTypeList extends StatelessWidget { +class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate { final SelectFieldCallback onSelectField; const FieldTypeList({required this.onSelectField, Key? key}) : super(key: key); - static void hide(BuildContext context) { - FlowyOverlay.of(context).remove(FieldTypeList.identifier()); - } - @override Widget build(BuildContext context) { final cells = FieldType.values.map((fieldType) { @@ -40,7 +37,7 @@ class FieldTypeList extends StatelessWidget { controller: ScrollController(), itemCount: cells.length, separatorBuilder: (context, index) { - return const VSpace(10); + return VSpace(GridSize.typeOptionSeparatorHeight); }, physics: StyledScrollPhysics(), itemBuilder: (BuildContext context, int index) { @@ -69,12 +66,12 @@ class FieldTypeCell extends StatelessWidget { final theme = context.watch(); return SizedBox( - height: 26, + height: GridSize.typeOptionItemHeight, child: FlowyButton( text: FlowyText.medium(fieldType.title(), fontSize: 12), hoverColor: theme.hover, onTap: () => onSelectField(fieldType), - leftIcon: svg(fieldType.iconName(), color: theme.iconColor), + leftIcon: svgWidget(fieldType.iconName(), color: theme.iconColor), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart index 956060039d..789b4f98bd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart @@ -9,7 +9,7 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class FieldOperationList extends StatelessWidget { - final List actions; + final List actions; const FieldOperationList({required this.actions, Key? key}) : super(key: key); @override @@ -27,12 +27,12 @@ class FieldOperationList extends StatelessWidget { } } -class FieldActionItem extends StatelessWidget { +class FieldActionCell extends StatelessWidget { final String fieldId; final VoidCallback onTap; final FieldAction action; - const FieldActionItem({ + const FieldActionCell({ required this.fieldId, required this.action, required this.onTap, @@ -49,7 +49,7 @@ class FieldActionItem extends StatelessWidget { action.run(context); onTap(); }, - leftIcon: svg(action.iconName(), color: theme.iconColor), + leftIcon: svgWidget(action.iconName(), color: theme.iconColor), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index 5f11d750d8..7c52c29a7e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -83,8 +83,8 @@ class _FieldSwitcherState extends State { }); _showOverlay(context, list); }, - leftIcon: svg(field.fieldType.iconName(), color: theme.iconColor), - rightIcon: svg("grid/more", color: theme.iconColor), + leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), + rightIcon: svgWidget("grid/more", color: theme.iconColor), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart index 13f9fbaba5..79dd083fab 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart @@ -17,16 +17,16 @@ class GridFieldActionSheet extends StatelessWidget with FlowyOverlayDelegate { final VoidCallback onEdited; const GridFieldActionSheet({required this.fieldData, required this.onEdited, Key? key}) : super(key: key); - static void show(BuildContext overlayContext, GridFieldData fieldData, final VoidCallback onEdited) { - final editor = GridFieldActionSheet(fieldData: fieldData, onEdited: onEdited); + void show(BuildContext overlayContext) { FlowyOverlay.of(overlayContext).insertWithAnchor( widget: OverlayContainer( - child: editor, + child: this, constraints: BoxConstraints.loose(const Size(240, 200)), ), - identifier: editor.identifier(), + identifier: identifier(), anchorContext: overlayContext, anchorDirection: AnchorDirection.bottomWithLeftAligned, + delegate: this, ); } @@ -56,7 +56,9 @@ class GridFieldActionSheet extends StatelessWidget with FlowyOverlayDelegate { } @override - bool asBarrier() => true; + bool asBarrier() { + return true; + } } class _EditFieldButton extends StatelessWidget { @@ -90,7 +92,7 @@ class _FieldOperationList extends StatelessWidget { Widget build(BuildContext context) { final actions = FieldAction.values .map( - (action) => FieldActionItem( + (action) => FieldActionCell( fieldId: fieldData.field.id, action: action, onTap: onDismissed, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart index 085f051699..4f349b9347 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart @@ -25,7 +25,7 @@ class FieldEditor extends FlowyOverlayDelegate { void show(BuildContext context) { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( - child: _EditFieldPannelWidget(_fieldEditorBloc), + child: _FieldEditorWidget(_fieldEditorBloc), constraints: BoxConstraints.loose(const Size(220, 400)), ), identifier: identifier(), @@ -49,9 +49,9 @@ class FieldEditor extends FlowyOverlayDelegate { bool asBarrier() => true; } -class _EditFieldPannelWidget extends StatelessWidget { +class _FieldEditorWidget extends StatelessWidget { final FieldEditorBloc editorBloc; - const _EditFieldPannelWidget(this.editorBloc, {Key? key}) : super(key: key); + const _FieldEditorWidget(this.editorBloc, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 6125cf4526..faf17e8c13 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -121,7 +121,7 @@ class CreateFieldButton extends StatelessWidget { gridId: gridId, fieldContextLoader: NewFieldContextLoader(gridId: gridId), ).show(context), - leftIcon: svg("home/add"), + leftIcon: svgWidget("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart index 4efedbfe6d..253f935bbd 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart @@ -19,13 +19,16 @@ class GridHeaderCell extends StatelessWidget { final theme = context.watch(); final button = FlowyButton( hoverColor: theme.hover, - onTap: () => GridFieldActionSheet.show(context, fieldData, () { - FieldEditor( - gridId: fieldData.gridId, - fieldContextLoader: FieldContextLoaderAdaptor(fieldData), - ).show(context); - }), - rightIcon: svg("editor/details", color: theme.iconColor), + onTap: () => GridFieldActionSheet( + fieldData: fieldData, + onEdited: () { + FieldEditor( + gridId: fieldData.gridId, + fieldContextLoader: FieldContextLoaderAdaptor(fieldData), + ).show(context); + }, + ).show(context), + rightIcon: svgWidget("editor/details", color: theme.iconColor), text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart deleted file mode 100644 index dff1058c52..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_setting.dart +++ /dev/null @@ -1,35 +0,0 @@ -enum GridSetting { - filter, - sortBy, - properties, -} - -extension _GridSettingExtension on GridSetting { - String iconName() { - switch (this) { - case GridSetting.filter: - // TODO: Handle this case. - break; - case GridSetting.sortBy: - // TODO: Handle this case. - break; - case GridSetting.properties: - // TODO: Handle this case. - break; - } - } - - String title() { - switch (this) { - case GridSetting.filter: - // TODO: Handle this case. - break; - case GridSetting.sortBy: - // TODO: Handle this case. - break; - case GridSetting.properties: - // TODO: Handle this case. - break; - } - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index 5057d5caee..bae78c02f8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -75,7 +75,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { ); overlayDelegate.showOverlay(context, list); }, - rightIcon: svg("grid/more", color: theme.iconColor), + rightIcon: svgWidget("grid/more", color: theme.iconColor), ), ); } @@ -96,7 +96,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { }); overlayDelegate.showOverlay(context, list); }, - rightIcon: svg("grid/more", color: theme.iconColor), + rightIcon: svgWidget("grid/more", color: theme.iconColor), ), ); } @@ -156,7 +156,7 @@ class DateFormatItem extends StatelessWidget { final theme = context.watch(); Widget? checkmark; if (isSelected) { - checkmark = svg("grid/checkmark"); + checkmark = svgWidget("grid/checkmark"); } return SizedBox( @@ -246,7 +246,7 @@ class TimeFormatItem extends StatelessWidget { final theme = context.watch(); Widget? checkmark; if (isSelected) { - checkmark = svg("grid/checkmark"); + checkmark = svgWidget("grid/checkmark"); } return SizedBox( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart index e7999b7e4c..4f133090de 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -79,7 +79,7 @@ class _DeleteTag extends StatelessWidget { child: FlowyButton( text: FlowyText.medium(LocaleKeys.grid_selectOption_deleteTag.tr(), fontSize: 12), hoverColor: theme.hover, - leftIcon: svg("grid/delete", color: theme.iconColor), + leftIcon: svgWidget("grid/delete", color: theme.iconColor), onTap: () { context.read().add(const EditOptionEvent.delete()); }, @@ -110,8 +110,8 @@ class SelectOptionColorList extends StatelessWidget { @override Widget build(BuildContext context) { - final optionItems = SelectOptionColor.values.map((color) { - return _SelectOptionColorItem(color: color, isSelected: selectedColor == color); + final cells = SelectOptionColor.values.map((color) { + return _SelectOptionColorCell(color: color, isSelected: selectedColor == color); }).toList(); return Column( @@ -135,10 +135,10 @@ class SelectOptionColorList extends StatelessWidget { separatorBuilder: (context, index) { return VSpace(GridSize.typeOptionSeparatorHeight); }, - itemCount: optionItems.length, + itemCount: cells.length, physics: StyledScrollPhysics(), itemBuilder: (BuildContext context, int index) { - return optionItems[index]; + return cells[index]; }, ), ], @@ -146,17 +146,17 @@ class SelectOptionColorList extends StatelessWidget { } } -class _SelectOptionColorItem extends StatelessWidget { +class _SelectOptionColorCell extends StatelessWidget { final SelectOptionColor color; final bool isSelected; - const _SelectOptionColorItem({required this.color, required this.isSelected, Key? key}) : super(key: key); + const _SelectOptionColorCell({required this.color, required this.isSelected, Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); Widget? checkmark; if (isSelected) { - checkmark = svg("grid/checkmark"); + checkmark = svgWidget("grid/checkmark"); } final colorIcon = SizedBox.square( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index bbff9dd5ad..a12b7e2be9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -59,7 +59,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget { }); overlayDelegate.showOverlay(context, list); }, - rightIcon: svg("grid/more", color: theme.iconColor), + rightIcon: svgWidget("grid/more", color: theme.iconColor), ); }, ), @@ -76,8 +76,8 @@ class NumberFormatList extends StatelessWidget { @override Widget build(BuildContext context) { - final formatItems = NumberFormat.values.map((format) { - return NumberFormatItem( + final cells = NumberFormat.values.map((format) { + return NumberFormatCell( format: format, onSelected: (format) { onSelected(format); @@ -93,9 +93,9 @@ class NumberFormatList extends StatelessWidget { separatorBuilder: (context, index) { return VSpace(GridSize.typeOptionSeparatorHeight); }, - itemCount: formatItems.length, + itemCount: cells.length, itemBuilder: (BuildContext context, int index) { - return formatItems[index]; + return cells[index]; }, ), ); @@ -106,10 +106,10 @@ class NumberFormatList extends StatelessWidget { } } -class NumberFormatItem extends StatelessWidget { +class NumberFormatCell extends StatelessWidget { final NumberFormat format; final Function(NumberFormat format) onSelected; - const NumberFormatItem({required this.format, required this.onSelected, Key? key}) : super(key: key); + const NumberFormatCell({required this.format, required this.onSelected, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -120,7 +120,7 @@ class NumberFormatItem extends StatelessWidget { text: FlowyText.medium(format.title(), fontSize: 12), hoverColor: theme.hover, onTap: () => onSelected(format), - leftIcon: svg(format.iconName(), color: theme.iconColor), + leftIcon: svgWidget(format.iconName(), color: theme.iconColor), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart index b4039bbce1..7c93f63ee7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart @@ -132,8 +132,8 @@ class _OptionList extends StatelessWidget { return previous.options != current.options; }, builder: (context, state) { - final optionItems = state.options.map((option) { - return _makeOptionItem(context, option); + final cells = state.options.map((option) { + return _makeOptionCell(context, option); }).toList(); return ListView.separated( @@ -142,17 +142,17 @@ class _OptionList extends StatelessWidget { separatorBuilder: (context, index) { return VSpace(GridSize.typeOptionSeparatorHeight); }, - itemCount: optionItems.length, + itemCount: cells.length, itemBuilder: (BuildContext context, int index) { - return optionItems[index]; + return cells[index]; }, ); }, ); } - _OptionItem _makeOptionItem(BuildContext context, SelectOption option) { - return _OptionItem( + _OptionCell _makeOptionCell(BuildContext context, SelectOption option) { + return _OptionCell( option: option, onEdited: (option) { final pannel = EditSelectOptionPannel( @@ -173,10 +173,10 @@ class _OptionList extends StatelessWidget { } } -class _OptionItem extends StatelessWidget { +class _OptionCell extends StatelessWidget { final SelectOption option; final Function(SelectOption) onEdited; - const _OptionItem({ + const _OptionCell({ required this.option, required this.onEdited, Key? key, @@ -191,7 +191,7 @@ class _OptionItem extends StatelessWidget { text: FlowyText.medium(option.name, fontSize: 12), hoverColor: theme.hover, onTap: () => onEdited(option), - rightIcon: svg("grid/details", color: theme.iconColor), + rightIcon: svgWidget("grid/details", color: theme.iconColor), ), ); } @@ -211,7 +211,7 @@ class _AddOptionButton extends StatelessWidget { onTap: () { context.read().add(const OptionPannelEvent.beginAddingOption()); }, - leftIcon: svg("home/add", color: theme.iconColor), + leftIcon: svgWidget("home/add", color: theme.iconColor), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart new file mode 100644 index 0000000000..756b7cdf17 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class GridPropertyList extends StatelessWidget { + const GridPropertyList({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); + } +} + +class _GridPropertyCell extends StatelessWidget { + const _GridPropertyCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart new file mode 100644 index 0000000000..784fd62bcf --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart @@ -0,0 +1,152 @@ +import 'package:app_flowy/workspace/application/grid/setting/setting_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; + +class GridSettingContext { + final String gridId; + GridSettingContext({ + required this.gridId, + }); +} + +class GridSettingList extends StatelessWidget with FlowyOverlayDelegate { + final GridSettingContext settingContext; + const GridSettingList({required this.settingContext, Key? key}) : super(key: key); + + void show(BuildContext context) { + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: this, + constraints: BoxConstraints.loose(const Size(140, 400)), + ), + identifier: identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomRight, + style: FlowyOverlayStyle(blur: false), + delegate: this, + ); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => GridSettingBloc(gridId: settingContext.gridId), + child: BlocListener( + listenWhen: (previous, current) => previous.selectedAction != current.selectedAction, + listener: (context, state) { + state.selectedAction.foldLeft(null, (_, action) { + switch (action) { + case GridSettingAction.filter: + // TODO: Handle this case. + break; + case GridSettingAction.sortBy: + // TODO: Handle this case. + break; + case GridSettingAction.properties: + // TODO: Handle this case. + break; + } + }); + }, + child: BlocBuilder( + builder: (context, state) { + return _renderList(); + }, + ), + ), + ); + } + + String identifier() { + return toString(); + } + + Widget _renderList() { + final cells = GridSettingAction.values.map((action) { + return _SettingItem(action: action); + }).toList(); + + return SizedBox( + width: 140, + child: ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + itemCount: cells.length, + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + ), + ); + } +} + +class _SettingItem extends StatelessWidget { + final GridSettingAction action; + + const _SettingItem({ + required this.action, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final isSelected = context + .read() + .state + .selectedAction + .foldLeft(false, (_, selectedAction) => selectedAction == action); + + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + isSelected: isSelected, + text: FlowyText.medium(action.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + context.read().add(GridSettingEvent.performAction(action)); + }, + leftIcon: svgWidget(action.iconName(), color: theme.iconColor), + ), + ); + } +} + +extension _GridSettingExtension on GridSettingAction { + String iconName() { + switch (this) { + case GridSettingAction.filter: + return 'grid/setting/filter'; + case GridSettingAction.sortBy: + return 'grid/setting/sort'; + case GridSettingAction.properties: + return 'grid/setting/properties'; + } + } + + String title() { + switch (this) { + case GridSettingAction.filter: + return LocaleKeys.grid_settings_filter.tr(); + case GridSettingAction.sortBy: + return LocaleKeys.grid_settings_sortBy.tr(); + case GridSettingAction.properties: + return LocaleKeys.grid_settings_Properties.tr(); + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart new file mode 100644 index 0000000000..dd586d9d2f --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart @@ -0,0 +1,44 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra_ui/style_widget/extension.dart'; +import 'package:flutter/material.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'grid_setting.dart'; + +class GridToolbar extends StatelessWidget { + final String gridId; + const GridToolbar({required this.gridId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 40, + child: Row( + children: [ + SizedBox(width: GridSize.leadingHeaderPadding), + _SettingButton(settingContext: GridSettingContext(gridId: gridId)), + const Spacer(), + ], + ), + ); + } +} + +class _SettingButton extends StatelessWidget { + final GridSettingContext settingContext; + const _SettingButton({required this.settingContext, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyIconButton( + hoverColor: theme.hover, + width: 22, + onPressed: () => GridSettingList(settingContext: settingContext).show(context), + icon: svgWidget("grid/setting/setting").padding(horizontal: 3, vertical: 3), + ); + } +} 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 ccd1c85188..770889c610 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart @@ -36,7 +36,7 @@ class MenuTrash extends StatelessWidget { child: Selector( selector: (ctx, notifier) => notifier.theme, builder: (ctx, theme, child) => - SizedBox(width: 16, height: 16, child: svg("home/trash", color: theme.iconColor)), + SizedBox(width: 16, height: 16, child: svgWidget("home/trash", color: theme.iconColor)), ), ), const HSpace(6), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/src/trash_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/src/trash_cell.dart index 4ba52edfe1..2c9679d97d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/src/trash_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/src/trash_cell.dart @@ -29,13 +29,13 @@ class TrashCell extends StatelessWidget { FlowyIconButton( width: 16, onPressed: onRestore, - icon: svg("editor/restore", color: theme.iconColor), + icon: svgWidget("editor/restore", color: theme.iconColor), ), const HSpace(20), FlowyIconButton( width: 16, onPressed: onDelete, - icon: svg("editor/delete", color: theme.iconColor), + icon: svgWidget("editor/delete", color: theme.iconColor), ), ], ); 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 14b12d77bf..324b676fc3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart @@ -146,7 +146,7 @@ class _TrashPageState extends State { size: const Size(102, 30), child: FlowyButton( text: FlowyText.medium(LocaleKeys.trash_restoreAll.tr(), fontSize: 12), - leftIcon: svg('editor/restore', color: theme.iconColor), + leftIcon: svgWidget('editor/restore', color: theme.iconColor), hoverColor: theme.hover, onTap: () => context.read().add(const TrashEvent.restoreAll()), ), @@ -156,7 +156,7 @@ class _TrashPageState extends State { size: const Size(102, 30), child: FlowyButton( text: FlowyText.medium(LocaleKeys.trash_deleteAll.tr(), fontSize: 12), - leftIcon: svg('editor/delete', color: theme.iconColor), + leftIcon: svgWidget('editor/delete', color: theme.iconColor), hoverColor: theme.hover, onTap: () => context.read().add(const TrashEvent.deleteAll()), ), diff --git a/frontend/app_flowy/packages/flowy_infra/lib/image.dart b/frontend/app_flowy/packages/flowy_infra/lib/image.dart index 68bea3cd6d..e70c8b4bff 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/image.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/image.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; -Widget svg(String name, {Color? color}) { +Widget svgWidget(String name, {Color? color}) { final Widget svg = SvgPicture.asset('assets/images/$name.svg', color: color); return svg; @@ -10,6 +10,6 @@ Widget svg(String name, {Color? color}) { Widget svgWithSize(String name, Size size) { return SizedBox.fromSize( size: size, - child: svg(name), + child: svgWidget(name), ); } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 13d02a0ea8..69cddbf2fb 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -11,6 +11,7 @@ class FlowyButton extends StatelessWidget { final Widget? leftIcon; final Widget? rightIcon; final Color hoverColor; + final bool isSelected; const FlowyButton({ Key? key, required this.text, @@ -19,6 +20,7 @@ class FlowyButton extends StatelessWidget { this.leftIcon, this.rightIcon, this.hoverColor = Colors.transparent, + this.isSelected = false, }) : super(key: key); @override @@ -27,6 +29,7 @@ class FlowyButton extends StatelessWidget { onTap: onTap, child: FlowyHover( config: HoverDisplayConfig(borderRadius: Corners.s6Border, hoverColor: hoverColor), + setSelected: () => isSelected, builder: (context, onHover) => _render(), ), ); diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index b19578fe54..48a702c2e4 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -3,18 +3,17 @@ import 'package:flutter/material.dart'; import 'package:flowy_infra/time/duration.dart'; typedef HoverBuilder = Widget Function(BuildContext context, bool onHover); -typedef IsOnSelected = bool Function(); class FlowyHover extends StatefulWidget { final HoverDisplayConfig config; final HoverBuilder builder; - final IsOnSelected? isOnSelected; + final bool Function()? setSelected; const FlowyHover({ Key? key, required this.builder, required this.config, - this.isOnSelected, + this.setSelected, }) : super(key: key); @override @@ -36,8 +35,8 @@ class _FlowyHoverState extends State { Widget render() { var showHover = _onHover; - if (!showHover && widget.isOnSelected != null) { - showHover = widget.isOnSelected!(); + if (!showHover && widget.setSelected != null) { + showHover = widget.setSelected!(); } if (showHover) { diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart index 79e9c648ea..f3ecd23005 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart @@ -77,7 +77,7 @@ class FlowyDropdownButton extends StatelessWidget { return FlowyIconButton( width: 16, onPressed: onPressed, - icon: svg("home/drop_down_show"), + icon: svgWidget("home/drop_down_show"), ); } } diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 2cc96e75d6..ad1f6cd0e2 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -113,6 +113,7 @@ flutter: - assets/images/editor/ - assets/images/grid/ - assets/images/grid/field/ + - assets/images/grid/setting/ - assets/translations/ # - images/a_dot_ham.jpeg From 6a94594a35db7a5fb81103a3ee86abc6b89f2fe3 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 3 Apr 2022 17:05:28 +0800 Subject: [PATCH 090/179] chore: grid property list --- .../app_flowy/lib/startup/deps_resolver.dart | 12 +- ...field_bloc.dart => action_sheet_bloc.dart} | 30 +-- ...field_bloc.dart => field_editor_bloc.dart} | 2 +- .../application/grid/field/field_service.dart | 6 +- ..._type_bloc.dart => field_switch_bloc.dart} | 6 +- .../grid/field/grid_header_bloc.dart | 6 +- .../workspace/application/grid/prelude.dart | 7 +- .../grid/setting/property_bloc.dart | 51 +++++ .../plugins/grid/src/grid_page.dart | 27 ++- .../grid/src/widgets/content/grid_row.dart | 1 + .../grid/src/widgets/header/field_cell.dart | 55 +++++ .../header/field_cell_action_sheet.dart | 195 ++++++++++++++++++ ...id_field_editor.dart => field_editor.dart} | 12 +- .../widgets/header/field_operation_list.dart | 99 --------- .../src/widgets/header/field_switcher.dart | 11 +- .../widgets/header/field_type_extension.dart | 44 ++++ .../{field_list.dart => field_type_list.dart} | 43 +--- .../header/grid_field_action_sheet.dart | 105 ---------- .../grid/src/widgets/header/grid_header.dart | 8 +- .../src/widgets/header/grid_header_cell.dart | 45 ---- .../src/widgets/header/type_option/date.dart | 24 +-- .../src/widgets/toolbar/grid_property.dart | 114 +++++++++- .../src/widgets/toolbar/grid_setting.dart | 48 +++-- .../src/widgets/toolbar/grid_toolbar.dart | 29 ++- .../flowy-grid/src/services/grid_editor.rs | 2 +- 25 files changed, 600 insertions(+), 382 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/field/{grid_field_bloc.dart => action_sheet_bloc.dart} (66%) rename frontend/app_flowy/lib/workspace/application/grid/field/{edit_field_bloc.dart => field_editor_bloc.dart} (98%) rename frontend/app_flowy/lib/workspace/application/grid/field/{switch_field_type_bloc.dart => field_switch_bloc.dart} (90%) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{grid_field_editor.dart => field_editor.dart} (89%) delete mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{field_list.dart => field_type_list.dart} (64%) delete mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart delete mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 1bb46f913f..9020101083 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -165,8 +165,8 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (data, _) => GridFieldBloc( + getIt.registerFactoryParam( + (data, _) => FieldActionSheetBloc( field: data.field, service: FieldService(gridId: data.gridId), ), @@ -214,8 +214,8 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (context, _) => FieldSwitchBloc(context), + getIt.registerFactoryParam( + (context, _) => FieldSwitcherBloc(context), ); getIt.registerFactoryParam( @@ -233,4 +233,8 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (typeOption, _) => NumberTypeOptionBloc(typeOption: typeOption), ); + + getIt.registerFactoryParam>( + (gridId, fields) => GridPropertyBloc(gridId: gridId, fields: fields), + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/action_sheet_bloc.dart similarity index 66% rename from frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/action_sheet_bloc.dart index f3ec3b4cbe..5e8cb5a932 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/action_sheet_bloc.dart @@ -5,14 +5,14 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'field_service.dart'; -part 'grid_field_bloc.freezed.dart'; +part 'action_sheet_bloc.freezed.dart'; -class GridFieldBloc extends Bloc { +class FieldActionSheetBloc extends Bloc { final FieldService service; - GridFieldBloc({required Field field, required this.service}) - : super(GridFieldState.initial(EditFieldContext.create()..gridField = field)) { - on( + FieldActionSheetBloc({required Field field, required this.service}) + : super(ActionSheetState.initial(EditFieldContext.create()..gridField = field)) { + on( (event, emit) async { await event.map( updateFieldName: (_UpdateFieldName value) async { @@ -56,23 +56,23 @@ class GridFieldBloc extends Bloc { } @freezed -class GridFieldEvent with _$GridFieldEvent { - const factory GridFieldEvent.updateFieldName(String name) = _UpdateFieldName; - const factory GridFieldEvent.hideField() = _HideField; - const factory GridFieldEvent.duplicateField() = _DuplicateField; - const factory GridFieldEvent.deleteField() = _DeleteField; - const factory GridFieldEvent.saveField() = _SaveField; +class ActionSheetEvent with _$ActionSheetEvent { + const factory ActionSheetEvent.updateFieldName(String name) = _UpdateFieldName; + const factory ActionSheetEvent.hideField() = _HideField; + const factory ActionSheetEvent.duplicateField() = _DuplicateField; + const factory ActionSheetEvent.deleteField() = _DeleteField; + const factory ActionSheetEvent.saveField() = _SaveField; } @freezed -class GridFieldState with _$GridFieldState { - const factory GridFieldState({ +class ActionSheetState with _$ActionSheetState { + const factory ActionSheetState({ required EditFieldContext editContext, required String errorText, required String fieldName, - }) = _GridFieldState; + }) = _ActionSheetState; - factory GridFieldState.initial(EditFieldContext editContext) => GridFieldState( + factory ActionSheetState.initial(EditFieldContext editContext) => ActionSheetState( editContext: editContext, errorText: '', fieldName: editContext.gridField.name, diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart similarity index 98% rename from frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart index 749cde3420..4556e17d38 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/edit_field_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'field_service.dart'; import 'package:dartz/dartz.dart'; -part 'edit_field_bloc.freezed.dart'; +part 'field_editor_bloc.freezed.dart'; class FieldEditorBloc extends Bloc { final FieldService service; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 5bb80a0119..d47dab99d0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -98,11 +98,11 @@ class FieldService { } } -class GridFieldData extends Equatable { +class GridFieldCellContext extends Equatable { final String gridId; final Field field; - const GridFieldData({ + const GridFieldCellContext({ required this.gridId, required this.field, }); @@ -132,7 +132,7 @@ class NewFieldContextLoader extends FieldContextLoader { } class FieldContextLoaderAdaptor extends FieldContextLoader { - final GridFieldData data; + final GridFieldCellContext data; FieldContextLoaderAdaptor(this.data); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart similarity index 90% rename from frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart index edb0732ddf..802b39d95a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/switch_field_type_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart @@ -7,10 +7,10 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'field_service.dart'; -part 'switch_field_type_bloc.freezed.dart'; +part 'field_switch_bloc.freezed.dart'; -class FieldSwitchBloc extends Bloc { - FieldSwitchBloc(SwitchFieldContext editContext) : super(FieldSwitchState.initial(editContext)) { +class FieldSwitcherBloc extends Bloc { + FieldSwitcherBloc(SwitchFieldContext editContext) : super(FieldSwitchState.initial(editContext)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart index d249e9b4c1..ae10505bc7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -27,6 +27,7 @@ class GridHeaderBloc extends Bloc { createField: (_CreateField value) {}, insertField: (_InsertField value) {}, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + value.fields.retainWhere((field) => field.visibility); emit(state.copyWith(fields: value.fields)); }, ); @@ -64,5 +65,8 @@ class GridHeaderEvent with _$GridHeaderEvent { class GridHeaderState with _$GridHeaderState { const factory GridHeaderState({required List fields}) = _GridHeaderState; - factory GridHeaderState.initial(List fields) => GridHeaderState(fields: fields); + factory GridHeaderState.initial(List fields) { + fields.retainWhere((field) => field.visibility); + return GridHeaderState(fields: fields); + } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 6c766ee218..f941b01056 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -7,9 +7,9 @@ export 'data.dart'; // Field export 'field/field_service.dart'; export 'field/grid_header_bloc.dart'; -export 'field/grid_field_bloc.dart'; -export 'field/edit_field_bloc.dart'; -export 'field/switch_field_type_bloc.dart'; +export 'field/action_sheet_bloc.dart'; +export 'field/field_editor_bloc.dart'; +export 'field/field_switch_bloc.dart'; // Field Type Option export 'field/type_option/date_bloc.dart'; @@ -26,3 +26,4 @@ export 'cell_bloc/cell_service.dart'; // Setting export 'setting/setting_bloc.dart'; +export 'setting/property_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart new file mode 100644 index 0000000000..a0dd50a633 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -0,0 +1,51 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'property_bloc.freezed.dart'; + +class GridPropertyBloc extends Bloc { + final FieldService _service; + GridPropertyBloc({required String gridId, required List fields}) + : _service = FieldService(gridId: gridId), + super(GridPropertyState.initial(gridId, fields)) { + on( + (event, emit) async { + await event.map(setFieldVisibility: (_SetFieldVisibility value) async { + final result = await _service.updateField(fieldId: value.fieldId, visibility: value.visibility); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class GridPropertyEvent with _$GridPropertyEvent { + const factory GridPropertyEvent.setFieldVisibility(String fieldId, bool visibility) = _SetFieldVisibility; +} + +@freezed +class GridPropertyState with _$GridPropertyState { + const factory GridPropertyState({ + required String gridId, + required List fields, + }) = _GridPropertyState; + + factory GridPropertyState.initial(String gridId, List fields) => GridPropertyState( + gridId: gridId, + fields: fields, + ); +} 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 1a8b5f4036..c8c5cfd7b2 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 @@ -100,9 +100,9 @@ class _FlowyGridState extends State { physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ - SliverToBoxAdapter(child: GridToolbar(gridId: gridId)), - _buildHeader(gridId), - _buildRows(context), + _renderToolbar(gridId), + _renderHeader(gridId), + _renderRows(context), const GridFooter(), ], ), @@ -129,12 +129,27 @@ class _FlowyGridState extends State { ); } - Widget _buildHeader(String gridId) { + Widget _renderToolbar(String gridId) { + return BlocBuilder( + builder: (context, state) { + final toolbarContext = GridToolbarContext( + gridId: gridId, + fields: state.fields, + ); + + return SliverToBoxAdapter( + child: GridToolbar(toolbarContext: toolbarContext), + ); + }, + ); + } + + Widget _renderHeader(String gridId) { return BlocBuilder( buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { return SliverPersistentHeader( - delegate: GridHeaderDelegate(gridId: gridId, fields: state.fields), + delegate: GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)), floating: true, pinned: true, ); @@ -142,7 +157,7 @@ class _FlowyGridState extends State { ); } - Widget _buildRows(BuildContext context) { + Widget _renderRows(BuildContext context) { return BlocBuilder( buildWhen: (previous, current) { final rowChanged = previous.rows.length != current.rows.length; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 53c27d62b4..73594de957 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -124,6 +124,7 @@ class _RowCells extends StatelessWidget { buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { final children = state.fields + .where((field) => field.visibility) .map((field) => CellContainer( width: field.width.toDouble(), child: buildGridCell( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart new file mode 100755 index 0000000000..6a2051318e --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -0,0 +1,55 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'field_type_extension.dart'; + +import 'field_cell_action_sheet.dart'; +import 'field_editor.dart'; + +class GridFieldCell extends StatelessWidget { + final GridFieldCellContext fieldCellContext; + const GridFieldCell(this.fieldCellContext, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final field = fieldCellContext.field; + + final button = FlowyButton( + hoverColor: theme.hover, + onTap: () => _showActionSheet(context), + rightIcon: svgWidget("editor/details", color: theme.iconColor), + leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), + text: FlowyText.medium(field.name, fontSize: 12), + padding: GridSize.cellContentInsets, + ); + + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); + + return Container( + width: field.width.toDouble(), + decoration: decoration, + child: button, + ); + } + + void _showActionSheet(BuildContext context) { + GridFieldCellActionSheet( + fieldCellContext: fieldCellContext, + onEdited: () => _showFieldEditor(context), + ).show(context); + } + + void _showFieldEditor(BuildContext context) { + FieldEditor( + gridId: fieldCellContext.gridId, + fieldContextLoader: FieldContextLoaderAdaptor(fieldCellContext), + ).show(context); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart new file mode 100644 index 0000000000..6cf62bf397 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart @@ -0,0 +1,195 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; + +class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate { + final GridFieldCellContext fieldCellContext; + final VoidCallback onEdited; + const GridFieldCellActionSheet({required this.fieldCellContext, required this.onEdited, Key? key}) : super(key: key); + + void show(BuildContext overlayContext) { + FlowyOverlay.of(overlayContext).insertWithAnchor( + widget: OverlayContainer( + child: this, + constraints: BoxConstraints.loose(const Size(240, 200)), + ), + identifier: identifier(), + anchorContext: overlayContext, + anchorDirection: AnchorDirection.bottomWithLeftAligned, + delegate: this, + ); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: fieldCellContext), + child: SingleChildScrollView( + child: Column( + children: [ + _EditFieldButton( + onEdited: () { + FlowyOverlay.of(context).remove(identifier()); + onEdited(); + }, + ), + const VSpace(6), + _FieldOperationList(fieldCellContext, () => FlowyOverlay.of(context).remove(identifier())), + ], + ), + ), + ); + } + + String identifier() { + return toString(); + } + + @override + bool asBarrier() { + return true; + } +} + +class _EditFieldButton extends StatelessWidget { + final Function() onEdited; + const _EditFieldButton({required this.onEdited, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocBuilder( + builder: (context, state) { + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12), + hoverColor: theme.hover, + onTap: onEdited, + ), + ); + }, + ); + } +} + +class _FieldOperationList extends StatelessWidget { + final GridFieldCellContext fieldData; + final VoidCallback onDismissed; + const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final actions = FieldAction.values + .map( + (action) => FieldActionCell( + fieldId: fieldData.field.id, + action: action, + onTap: onDismissed, + ), + ) + .toList(); + + return FieldOperationList(actions: actions); + } +} + +class FieldOperationList extends StatelessWidget { + final List actions; + const FieldOperationList({required this.actions, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return GridView( + // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.0, + mainAxisSpacing: 8, + ), + children: actions, + ); + } +} + +class FieldActionCell extends StatelessWidget { + final String fieldId; + final VoidCallback onTap; + final FieldAction action; + + const FieldActionCell({ + required this.fieldId, + required this.action, + required this.onTap, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: FlowyText.medium(action.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + action.run(context); + onTap(); + }, + leftIcon: svgWidget(action.iconName(), color: theme.iconColor), + ); + } +} + +enum FieldAction { + hide, + duplicate, + delete, +} + +extension _FieldActionExtension on FieldAction { + String iconName() { + switch (this) { + case FieldAction.hide: + return 'grid/hide'; + case FieldAction.duplicate: + return 'grid/duplicate'; + case FieldAction.delete: + return 'grid/delete'; + } + } + + String title() { + switch (this) { + case FieldAction.hide: + return LocaleKeys.grid_field_hide.tr(); + case FieldAction.duplicate: + return LocaleKeys.grid_field_duplicate.tr(); + case FieldAction.delete: + return LocaleKeys.grid_field_delete.tr(); + } + } + + void run(BuildContext context) { + switch (this) { + case FieldAction.hide: + context.read().add(const ActionSheetEvent.hideField()); + break; + case FieldAction.duplicate: + context.read().add(const ActionSheetEvent.duplicateField()); + break; + case FieldAction.delete: + context.read().add(const ActionSheetEvent.deleteField()); + break; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart similarity index 89% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index 4f349b9347..d568829558 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -1,7 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/field/edit_field_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; -import 'package:app_flowy/workspace/application/grid/field/switch_field_type_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_switch_bloc.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; @@ -22,7 +22,11 @@ class FieldEditor extends FlowyOverlayDelegate { _fieldEditorBloc.add(const FieldEditorEvent.initial()); } - void show(BuildContext context) { + void show( + BuildContext context, { + AnchorDirection anchorDirection = AnchorDirection.bottomWithLeftAligned, + }) { + FlowyOverlay.of(context).remove(identifier()); FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: _FieldEditorWidget(_fieldEditorBloc), @@ -30,7 +34,7 @@ class FieldEditor extends FlowyOverlayDelegate { ), identifier: identifier(), anchorContext: context, - anchorDirection: AnchorDirection.bottomWithLeftAligned, + anchorDirection: anchorDirection, style: FlowyOverlayStyle(blur: false), delegate: this, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart deleted file mode 100644 index 789b4f98bd..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_operation_list.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'package:app_flowy/workspace/application/grid/field/grid_field_bloc.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flutter/material.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:app_flowy/generated/locale_keys.g.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -class FieldOperationList extends StatelessWidget { - final List actions; - const FieldOperationList({required this.actions, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return GridView( - // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html - shrinkWrap: true, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 4.0, - mainAxisSpacing: 8, - ), - children: actions, - ); - } -} - -class FieldActionCell extends StatelessWidget { - final String fieldId; - final VoidCallback onTap; - final FieldAction action; - - const FieldActionCell({ - required this.fieldId, - required this.action, - required this.onTap, - Key? key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return FlowyButton( - text: FlowyText.medium(action.title(), fontSize: 12), - hoverColor: theme.hover, - onTap: () { - action.run(context); - onTap(); - }, - leftIcon: svgWidget(action.iconName(), color: theme.iconColor), - ); - } -} - -enum FieldAction { - hide, - duplicate, - delete, -} - -extension _FieldActionExtension on FieldAction { - String iconName() { - switch (this) { - case FieldAction.hide: - return 'grid/hide'; - case FieldAction.duplicate: - return 'grid/duplicate'; - case FieldAction.delete: - return 'grid/delete'; - } - } - - String title() { - switch (this) { - case FieldAction.hide: - return LocaleKeys.grid_field_hide.tr(); - case FieldAction.duplicate: - return LocaleKeys.grid_field_duplicate.tr(); - case FieldAction.delete: - return LocaleKeys.grid_field_delete.tr(); - } - } - - void run(BuildContext context) { - switch (this) { - case FieldAction.hide: - context.read().add(const GridFieldEvent.hideField()); - break; - case FieldAction.duplicate: - context.read().add(const GridFieldEvent.duplicateField()); - break; - case FieldAction.delete: - context.read().add(const GridFieldEvent.deleteField()); - break; - } - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index 7c52c29a7e..63816c7d74 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -15,7 +15,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'field_type_extension.dart'; import 'type_option/multi_select.dart'; import 'type_option/number.dart'; @@ -43,8 +44,8 @@ class _FieldSwitcherState extends State { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: widget.switchContext), - child: BlocConsumer( + create: (context) => getIt(param1: widget.switchContext), + child: BlocConsumer( listener: (context, state) { widget.onUpdated(state.field, state.typeOptionData); }, @@ -79,7 +80,7 @@ class _FieldSwitcherState extends State { hoverColor: theme.hover, onTap: () { final list = FieldTypeList(onSelectField: (fieldType) { - context.read().add(FieldSwitchEvent.toFieldType(fieldType)); + context.read().add(FieldSwitchEvent.toFieldType(fieldType)); }); _showOverlay(context, list); }, @@ -100,7 +101,7 @@ class _FieldSwitcherState extends State { ); final dataDelegate = TypeOptionDataDelegate(didUpdateTypeOptionData: (data) { - context.read().add(FieldSwitchEvent.didUpdateTypeOptionData(data)); + context.read().add(FieldSwitchEvent.didUpdateTypeOptionData(data)); }); final builder = _makeTypeOptionBuild( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart new file mode 100644 index 0000000000..ce37afe861 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart @@ -0,0 +1,44 @@ + +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:easy_localization/easy_localization.dart'; + +extension FieldTypeListExtension on FieldType { + String iconName() { + switch (this) { + case FieldType.Checkbox: + return "grid/field/checkbox"; + case FieldType.DateTime: + return "grid/field/date"; + case FieldType.MultiSelect: + return "grid/field/multi_select"; + case FieldType.Number: + return "grid/field/number"; + case FieldType.RichText: + return "grid/field/text"; + case FieldType.SingleSelect: + return "grid/field/single_select"; + default: + throw UnimplementedError; + } + } + + String title() { + switch (this) { + case FieldType.Checkbox: + return LocaleKeys.grid_field_checkboxFieldName.tr(); + case FieldType.DateTime: + return LocaleKeys.grid_field_dateFieldName.tr(); + case FieldType.MultiSelect: + return LocaleKeys.grid_field_multiSelectFieldName.tr(); + case FieldType.Number: + return LocaleKeys.grid_field_numberFieldName.tr(); + case FieldType.RichText: + return LocaleKeys.grid_field_textFieldName.tr(); + case FieldType.SingleSelect: + return LocaleKeys.grid_field_singleSelectFieldName.tr(); + default: + throw UnimplementedError; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart similarity index 64% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index b83ad267f9..2965556f60 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -8,8 +8,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; -import 'package:app_flowy/generated/locale_keys.g.dart'; -import 'package:easy_localization/easy_localization.dart'; +import 'field_type_extension.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; typedef SelectFieldCallback = void Function(FieldType); @@ -76,43 +75,3 @@ class FieldTypeCell extends StatelessWidget { ); } } - -extension FieldTypeListExtension on FieldType { - String iconName() { - switch (this) { - case FieldType.Checkbox: - return "grid/field/checkbox"; - case FieldType.DateTime: - return "grid/field/date"; - case FieldType.MultiSelect: - return "grid/field/multi_select"; - case FieldType.Number: - return "grid/field/number"; - case FieldType.RichText: - return "grid/field/text"; - case FieldType.SingleSelect: - return "grid/field/single_select"; - default: - throw UnimplementedError; - } - } - - String title() { - switch (this) { - case FieldType.Checkbox: - return LocaleKeys.grid_field_checkboxFieldName.tr(); - case FieldType.DateTime: - return LocaleKeys.grid_field_dateFieldName.tr(); - case FieldType.MultiSelect: - return LocaleKeys.grid_field_multiSelectFieldName.tr(); - case FieldType.Number: - return LocaleKeys.grid_field_numberFieldName.tr(); - case FieldType.RichText: - return LocaleKeys.grid_field_textFieldName.tr(); - case FieldType.SingleSelect: - return LocaleKeys.grid_field_singleSelectFieldName.tr(); - default: - throw UnimplementedError; - } - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart deleted file mode 100644 index 79dd083fab..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_field_action_sheet.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'field_operation_list.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:app_flowy/generated/locale_keys.g.dart'; - -class GridFieldActionSheet extends StatelessWidget with FlowyOverlayDelegate { - final GridFieldData fieldData; - final VoidCallback onEdited; - const GridFieldActionSheet({required this.fieldData, required this.onEdited, Key? key}) : super(key: key); - - void show(BuildContext overlayContext) { - FlowyOverlay.of(overlayContext).insertWithAnchor( - widget: OverlayContainer( - child: this, - constraints: BoxConstraints.loose(const Size(240, 200)), - ), - identifier: identifier(), - anchorContext: overlayContext, - anchorDirection: AnchorDirection.bottomWithLeftAligned, - delegate: this, - ); - } - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: fieldData), - child: SingleChildScrollView( - child: Column( - children: [ - _EditFieldButton( - onEdited: () { - FlowyOverlay.of(context).remove(identifier()); - onEdited(); - }, - ), - const VSpace(6), - _FieldOperationList(fieldData, () => FlowyOverlay.of(context).remove(identifier())), - ], - ), - ), - ); - } - - String identifier() { - return toString(); - } - - @override - bool asBarrier() { - return true; - } -} - -class _EditFieldButton extends StatelessWidget { - final Function() onEdited; - const _EditFieldButton({required this.onEdited, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return BlocBuilder( - builder: (context, state) { - return SizedBox( - height: GridSize.typeOptionItemHeight, - child: FlowyButton( - text: FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12), - hoverColor: theme.hover, - onTap: onEdited, - ), - ); - }, - ); - } -} - -class _FieldOperationList extends StatelessWidget { - final GridFieldData fieldData; - final VoidCallback onDismissed; - const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final actions = FieldAction.values - .map( - (action) => FieldActionCell( - fieldId: fieldData.field.id, - action: action, - onTap: onDismissed, - ), - ) - .toList(); - - return FieldOperationList(actions: actions); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index faf17e8c13..be025501a0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -9,8 +9,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'grid_field_editor.dart'; -import 'grid_header_cell.dart'; +import 'field_editor.dart'; +import 'field_cell.dart'; class GridHeaderDelegate extends SliverPersistentHeaderDelegate { final String gridId; @@ -55,8 +55,8 @@ class GridHeader extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final cells = state.fields.map( - (field) => GridHeaderCell( - GridFieldData(gridId: gridId, field: field), + (field) => GridFieldCell( + GridFieldCellContext(gridId: gridId, field: field), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart deleted file mode 100755 index 253f935bbd..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import 'grid_field_editor.dart'; -import 'grid_field_action_sheet.dart'; - -class GridHeaderCell extends StatelessWidget { - final GridFieldData fieldData; - const GridHeaderCell(this.fieldData, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - final button = FlowyButton( - hoverColor: theme.hover, - onTap: () => GridFieldActionSheet( - fieldData: fieldData, - onEdited: () { - FieldEditor( - gridId: fieldData.gridId, - fieldContextLoader: FieldContextLoaderAdaptor(fieldData), - ).show(context); - }, - ).show(context), - rightIcon: svgWidget("editor/details", color: theme.iconColor), - text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)), - ); - - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); - - return Container( - width: fieldData.field.width.toDouble(), - decoration: decoration, - padding: GridSize.headerContentInsets, - child: button, - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index bae78c02f8..a31d371b09 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -109,8 +109,8 @@ class DateFormatList extends StatelessWidget { @override Widget build(BuildContext context) { - final formatItems = DateFormat.values.map((format) { - return DateFormatItem( + final cells = DateFormat.values.map((format) { + return DateFormatCell( dateFormat: format, onSelected: (format) { onSelected(format); @@ -127,9 +127,9 @@ class DateFormatList extends StatelessWidget { separatorBuilder: (context, index) { return VSpace(GridSize.typeOptionSeparatorHeight); }, - itemCount: formatItems.length, + itemCount: cells.length, itemBuilder: (BuildContext context, int index) { - return formatItems[index]; + return cells[index]; }, ), ); @@ -140,11 +140,11 @@ class DateFormatList extends StatelessWidget { } } -class DateFormatItem extends StatelessWidget { +class DateFormatCell extends StatelessWidget { final bool isSelected; final DateFormat dateFormat; final Function(DateFormat format) onSelected; - const DateFormatItem({ + const DateFormatCell({ required this.dateFormat, required this.onSelected, required this.isSelected, @@ -199,8 +199,8 @@ class TimeFormatList extends StatelessWidget { @override Widget build(BuildContext context) { - final formatItems = TimeFormat.values.map((format) { - return TimeFormatItem( + final cells = TimeFormat.values.map((format) { + return TimeFormatCell( isSelected: format == selectedFormat, timeFormat: format, onSelected: (format) { @@ -217,9 +217,9 @@ class TimeFormatList extends StatelessWidget { separatorBuilder: (context, index) { return VSpace(GridSize.typeOptionSeparatorHeight); }, - itemCount: formatItems.length, + itemCount: cells.length, itemBuilder: (BuildContext context, int index) { - return formatItems[index]; + return cells[index]; }, ), ); @@ -230,11 +230,11 @@ class TimeFormatList extends StatelessWidget { } } -class TimeFormatItem extends StatelessWidget { +class TimeFormatCell extends StatelessWidget { final TimeFormat timeFormat; final bool isSelected; final Function(TimeFormat format) onSelected; - const TimeFormatItem({ + const TimeFormatCell({ required this.timeFormat, required this.onSelected, required this.isSelected, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index 756b7cdf17..b1c57a1530 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -1,19 +1,123 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/application/grid/setting/property_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:styled_widget/styled_widget.dart'; -class GridPropertyList extends StatelessWidget { - const GridPropertyList({Key? key}) : super(key: key); +class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { + final String gridId; + final List fields; + const GridPropertyList({ + required this.gridId, + required this.fields, + Key? key, + }) : super(key: key); + + void show(BuildContext context) { + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: this, + constraints: BoxConstraints.loose(const Size(260, 400)), + ), + identifier: identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomRight, + style: FlowyOverlayStyle(blur: false), + delegate: this, + ); + } @override Widget build(BuildContext context) { - return Container(); + return BlocProvider( + create: (context) => getIt(param1: gridId, param2: fields), + child: BlocBuilder( + builder: (context, state) { + final cells = state.fields.map((field) { + return _GridPropertyCell(gridId: gridId, field: field); + }).toList(); + + return ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + itemCount: cells.length, + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + ); + }, + ), + ); } + + String identifier() { + return toString(); + } + + @override + bool asBarrier() => true; } class _GridPropertyCell extends StatelessWidget { - const _GridPropertyCell({Key? key}) : super(key: key); + final Field field; + final String gridId; + const _GridPropertyCell({required this.gridId, required this.field, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return Container(); + final theme = context.watch(); + + final checkmark = field.visibility + ? svgWidget('home/show', color: theme.iconColor) + : svgWidget('home/hide', color: theme.iconColor); + + return Row( + children: [ + Expanded( + child: SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(field.name, fontSize: 12), + hoverColor: theme.hover, + leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), + onTap: () { + final fieldCellContext = GridFieldCellContext( + gridId: gridId, + field: field, + ); + + FieldEditor( + gridId: gridId, + fieldContextLoader: FieldContextLoaderAdaptor(fieldCellContext), + ).show(context, anchorDirection: AnchorDirection.bottomRight); + }, + ), + ), + ), + FlowyIconButton( + hoverColor: theme.hover, + width: GridSize.typeOptionItemHeight, + onPressed: () { + context.read().add(GridPropertyEvent.setFieldVisibility(field.id, !field.visibility)); + }, + icon: checkmark.padding(all: 6), + ) + ], + ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart index 784fd62bcf..e8a792025d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart @@ -7,34 +7,57 @@ import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'grid_property.dart'; + class GridSettingContext { final String gridId; + final List fields; + GridSettingContext({ required this.gridId, + required this.fields, }); } -class GridSettingList extends StatelessWidget with FlowyOverlayDelegate { +class GridSettingList extends StatelessWidget { final GridSettingContext settingContext; - const GridSettingList({required this.settingContext, Key? key}) : super(key: key); + final Function(GridSettingAction, GridSettingContext) onAction; + const GridSettingList({required this.settingContext, required this.onAction, Key? key}) : super(key: key); + + static void show(BuildContext context, GridSettingContext settingContext) { + final list = GridSettingList( + settingContext: settingContext, + onAction: (action, settingContext) { + switch (action) { + case GridSettingAction.filter: + // TODO: Handle this case. + break; + case GridSettingAction.sortBy: + // TODO: Handle this case. + break; + case GridSettingAction.properties: + GridPropertyList(gridId: settingContext.gridId, fields: settingContext.fields).show(context); + break; + } + }, + ); - void show(BuildContext context) { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( - child: this, + child: list, constraints: BoxConstraints.loose(const Size(140, 400)), ), - identifier: identifier(), + identifier: list.identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomRight, style: FlowyOverlayStyle(blur: false), - delegate: this, ); } @@ -46,17 +69,8 @@ class GridSettingList extends StatelessWidget with FlowyOverlayDelegate { listenWhen: (previous, current) => previous.selectedAction != current.selectedAction, listener: (context, state) { state.selectedAction.foldLeft(null, (_, action) { - switch (action) { - case GridSettingAction.filter: - // TODO: Handle this case. - break; - case GridSettingAction.sortBy: - // TODO: Handle this case. - break; - case GridSettingAction.properties: - // TODO: Handle this case. - break; - } + FlowyOverlay.of(context).remove(identifier()); + onAction(action, settingContext); }); }, child: BlocBuilder( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart index dd586d9d2f..9569f95225 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart @@ -1,25 +1,40 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/style_widget/extension.dart'; -import 'package:flutter/material.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/extension.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; + import 'grid_setting.dart'; -class GridToolbar extends StatelessWidget { +class GridToolbarContext { final String gridId; - const GridToolbar({required this.gridId, Key? key}) : super(key: key); + final List fields; + GridToolbarContext({ + required this.gridId, + required this.fields, + }); +} + +class GridToolbar extends StatelessWidget { + final GridToolbarContext toolbarContext; + const GridToolbar({required this.toolbarContext, Key? key}) : super(key: key); @override Widget build(BuildContext context) { + final settingContext = GridSettingContext( + gridId: toolbarContext.gridId, + fields: toolbarContext.fields, + ); return SizedBox( height: 40, child: Row( children: [ SizedBox(width: GridSize.leadingHeaderPadding), - _SettingButton(settingContext: GridSettingContext(gridId: gridId)), + _SettingButton(settingContext: settingContext), const Spacer(), ], ), @@ -37,7 +52,7 @@ class _SettingButton extends StatelessWidget { return FlowyIconButton( hoverColor: theme.hover, width: 22, - onPressed: () => GridSettingList(settingContext: settingContext).show(context), + onPressed: () => GridSettingList.show(context, settingContext), icon: svgWidget("grid/setting/setting").padding(horizontal: 3, vertical: 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 3925f80b24..95c23f489b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -295,7 +295,7 @@ impl ClientGridEditor { pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { let mut field_metas = self.pad.read().await.get_field_metas(field_orders)?; - field_metas.retain(|field_meta| field_meta.visibility); + // field_metas.retain(|field_meta| field_meta.visibility); Ok(field_metas) } From aa9e3d065b74d2ebca69627bdfd9837977120bb6 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 3 Apr 2022 20:29:06 +0800 Subject: [PATCH 091/179] chore: show and hide property --- .../grid/setting/property_bloc.dart | 42 +++++++-- .../plugins/grid/src/grid_page.dart | 12 +-- .../grid/src/widgets/content/number_cell.dart | 2 +- .../grid/src/widgets/header/grid_header.dart | 87 ++++++++++++------- .../src/widgets/toolbar/grid_property.dart | 3 +- 5 files changed, 98 insertions(+), 48 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index a0dd50a633..ab618b0fa9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -1,40 +1,66 @@ import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'package:dartz/dartz.dart'; part 'property_bloc.freezed.dart'; class GridPropertyBloc extends Bloc { final FieldService _service; + final GridFieldsListener _fieldListener; + GridPropertyBloc({required String gridId, required List fields}) : _service = FieldService(gridId: gridId), + _fieldListener = GridFieldsListener(gridId: gridId), super(GridPropertyState.initial(gridId, fields)) { on( (event, emit) async { - await event.map(setFieldVisibility: (_SetFieldVisibility value) async { - final result = await _service.updateField(fieldId: value.fieldId, visibility: value.visibility); - result.fold( - (l) => null, - (err) => Log.error(err), - ); - }); + await event.map( + initial: (_Initial value) { + _startListening(); + }, + setFieldVisibility: (_SetFieldVisibility value) async { + final result = await _service.updateField(fieldId: value.fieldId, visibility: value.visibility); + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + emit(state.copyWith(fields: value.fields)); + }, + ); }, ); } @override Future close() async { + await _fieldListener.stop(); return super.close(); } + + void _startListening() { + _fieldListener.updateFieldsNotifier.addPublishListener((result) { + result.fold( + (fields) { + add(GridPropertyEvent.didReceiveFieldUpdate(fields)); + }, + (err) => Log.error(err), + ); + }); + _fieldListener.start(); + } } @freezed class GridPropertyEvent with _$GridPropertyEvent { + const factory GridPropertyEvent.initial() = _Initial; const factory GridPropertyEvent.setFieldVisibility(String fieldId, bool visibility) = _SetFieldVisibility; + const factory GridPropertyEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @freezed 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 c8c5cfd7b2..83bce9c7ef 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 @@ -148,11 +148,13 @@ class _FlowyGridState extends State { return BlocBuilder( buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { - return SliverPersistentHeader( - delegate: GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)), - floating: true, - pinned: true, - ); + return GridHeader(gridId: gridId, fields: List.from(state.fields)); + + // return SliverPersistentHeader( + // delegate: GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)), + // floating: true, + // pinned: true, + // ); }, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 6983cc1015..bc51829412 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -38,7 +38,7 @@ class _NumberCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index be025501a0..80a7a51d59 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -12,15 +12,41 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_editor.dart'; import 'field_cell.dart'; -class GridHeaderDelegate extends SliverPersistentHeaderDelegate { +class GridHeader extends StatelessWidget { + final String gridId; + final List fields; + const GridHeader({Key? key, required this.gridId, required this.fields}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) { + final bloc = getIt(param1: gridId, param2: fields); + bloc.add(const GridHeaderEvent.initial()); + return bloc; + }, + child: BlocBuilder( + builder: (context, state) { + return SliverPersistentHeader( + delegate: _GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)), + floating: true, + pinned: true, + ); + }, + ), + ); + } +} + +class _GridHeaderDelegate extends SliverPersistentHeaderDelegate { final String gridId; final List fields; - GridHeaderDelegate({required this.gridId, required this.fields}); + _GridHeaderDelegate({required this.gridId, required this.fields}); @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return GridHeader(gridId: gridId, fields: fields, key: ObjectKey(fields)); + return _GridHeaderWidget(gridId: gridId, fields: fields, key: ObjectKey(fields)); } @override @@ -31,47 +57,42 @@ class GridHeaderDelegate extends SliverPersistentHeaderDelegate { @override bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { - if (oldDelegate is GridHeaderDelegate) { + if (oldDelegate is _GridHeaderDelegate) { return fields != oldDelegate.fields; } - return false; + return true; } } -class GridHeader extends StatelessWidget { - final List fields; +class _GridHeaderWidget extends StatelessWidget { final String gridId; - const GridHeader({required this.gridId, required this.fields, Key? key}) : super(key: key); + final List fields; + + const _GridHeaderWidget({required this.gridId, required this.fields, Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); - return BlocProvider( - create: (context) { - final bloc = getIt(param1: gridId, param2: fields); - bloc.add(const GridHeaderEvent.initial()); - return bloc; + return BlocBuilder( + builder: (context, state) { + final cells = state.fields.map( + (field) => GridFieldCell( + GridFieldCellContext(gridId: gridId, field: field), + ), + ); + + final row = Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _HeaderLeading(), + ...cells, + _HeaderTrailing(gridId: gridId), + ], + key: UniqueKey(), + ); + + return Container(height: GridSize.headerHeight, color: theme.surface, child: row); }, - child: BlocBuilder( - builder: (context, state) { - final cells = state.fields.map( - (field) => GridFieldCell( - GridFieldCellContext(gridId: gridId, field: field), - ), - ); - - final row = Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _HeaderLeading(), - ...cells, - _HeaderTrailing(gridId: gridId), - ], - ); - - return Container(color: theme.surface, child: row); - }, - ), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index b1c57a1530..9951e6ba65 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -42,7 +42,8 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: gridId, param2: fields), + create: (context) => + getIt(param1: gridId, param2: fields)..add(const GridPropertyEvent.initial()), child: BlocBuilder( builder: (context, state) { final cells = state.fields.map((field) { From 5c3500e24cb65f986dd5782a6102aa7b86398b4e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 3 Apr 2022 22:22:54 +0800 Subject: [PATCH 092/179] chore: cell select option editor --- .../grid/cell_bloc/selection_editor_bloc.dart | 102 ++++++++++++++++++ .../grid/field/field_listener.dart | 51 +++++++++ .../application/grid/field/field_service.dart | 14 ++- .../plugins/grid/src/grid_page.dart | 19 +--- .../{content => cell}/cell_builder.dart | 2 +- .../{content => cell}/cell_container.dart | 0 .../{content => cell}/cell_decoration.dart | 0 .../{content => cell}/checkbox_cell.dart | 0 .../widgets/{content => cell}/date_cell.dart | 0 .../{content => cell}/number_cell.dart | 0 .../grid/src/widgets/cell/prelude.dart | 7 ++ .../cell/selection_cell/selection.dart | 77 +++++++++++++ .../selection_cell}/selection_cell.dart | 0 .../cell/selection_cell/selection_editor.dart | 45 ++++++++ .../widgets/{content => cell}/text_cell.dart | 0 .../grid/src/widgets/header/field_cell.dart | 5 +- .../type_option/edit_option_pannel.dart | 54 +--------- .../widgets/{content => row}/grid_row.dart | 3 +- .../src/widgets/toolbar/grid_property.dart | 7 +- .../flowy-grid/dart_notification.pbenum.dart | 6 +- .../flowy-grid/dart_notification.pbjson.dart | 5 +- .../flowy-grid/src/dart_notification.rs | 6 +- .../src/protobuf/model/dart_notification.rs | 17 +-- .../protobuf/proto/dart_notification.proto | 3 +- .../flowy-grid/src/services/grid_editor.rs | 31 +++++- .../src/entities/grid.rs | 12 +++ 26 files changed, 364 insertions(+), 102 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/cell_builder.dart (96%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/cell_container.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/cell_decoration.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/checkbox_cell.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/date_cell.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/number_cell.dart (100%) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell/selection_cell}/selection_cell.dart (100%) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => cell}/text_cell.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/{content => row}/grid_row.dart (97%) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart new file mode 100644 index 0000000000..7e617069c4 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -0,0 +1,102 @@ +import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'cell_service.dart'; + +part 'selection_editor_bloc.freezed.dart'; + +class SelectionEditorBloc extends Bloc { + final CellService service = CellService(); + final FieldListener _listener; + + SelectionEditorBloc({ + required String gridId, + required Field field, + }) : _listener = FieldListener(fieldId: field.id), + super(SelectionEditorState.initial(gridId, field)) { + on( + (event, emit) async { + await event.map( + initial: (_Initial value) async { + _startListening(); + _loadOptions(); + }, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + emit(state.copyWith(field: value.field)); + _loadOptions(); + }, + didReceiveOptions: (_DidReceiveOptions value) { + emit(state.copyWith(options: value.options)); + }, + ); + }, + ); + } + + @override + Future close() async { + await _listener.stop(); + return super.close(); + } + + void _startListening() { + _listener.updateFieldNotifier.addPublishListener((result) { + result.fold( + (field) => add(SelectionEditorEvent.didReceiveFieldUpdate(field)), + (err) => Log.error(err), + ); + }); + } + + void _loadOptions() async { + final result = await FieldContextLoaderAdaptor(gridId: state.gridId, field: state.field).load(); + result.fold( + (context) { + List options = []; + switch (state.field.fieldType) { + case FieldType.MultiSelect: + options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options); + break; + case FieldType.SingleSelect: + options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options); + break; + default: + Log.error("Invalid field type, expect single select or multiple select"); + break; + } + add(SelectionEditorEvent.didReceiveOptions(options)); + }, + (err) => Log.error(err), + ); + } +} + +@freezed +class SelectionEditorEvent with _$SelectionEditorEvent { + const factory SelectionEditorEvent.initial() = _Initial; + const factory SelectionEditorEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate; + const factory SelectionEditorEvent.didReceiveOptions(List options) = _DidReceiveOptions; +} + +@freezed +class SelectionEditorState with _$SelectionEditorState { + const factory SelectionEditorState({ + required String gridId, + required Field field, + required List options, + }) = _SelectionEditorState; + + factory SelectionEditorState.initial(String gridId, Field field) { + return SelectionEditorState( + gridId: gridId, + field: field, + options: [], + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart new file mode 100644 index 0000000000..eda5d83e69 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart @@ -0,0 +1,51 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; + +typedef UpdateFieldNotifiedValue = Either; + +class FieldListener { + final String fieldId; + PublishNotifier updateFieldNotifier = PublishNotifier(); + StreamSubscription? _subscription; + GridNotificationParser? _parser; + + FieldListener({required this.fieldId}); + + void start() { + _parser = GridNotificationParser( + id: fieldId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.DidUpdateField: + result.fold( + (payload) => updateFieldNotifier.value = left(Field.fromBuffer(payload)), + (error) => updateFieldNotifier.value = right(error), + ); + break; + default: + break; + } + } + + Future stop() async { + _parser = null; + await _subscription?.cancel(); + updateFieldNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index d47dab99d0..61ccad6b81 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -132,16 +132,20 @@ class NewFieldContextLoader extends FieldContextLoader { } class FieldContextLoaderAdaptor extends FieldContextLoader { - final GridFieldCellContext data; + final String gridId; + final Field field; - FieldContextLoaderAdaptor(this.data); + FieldContextLoaderAdaptor({ + required this.gridId, + required this.field, + }); @override Future> load() { final payload = GetEditFieldContextPayload.create() - ..gridId = data.gridId - ..fieldId = data.field.id - ..fieldType = data.field.fieldType; + ..gridId = gridId + ..fieldId = field.id + ..fieldType = field.fieldType; return GridEventGetEditFieldContext(payload).send(); } 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 83bce9c7ef..111235841f 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 @@ -10,7 +10,7 @@ import 'package:flutter/material.dart'; import 'controller/grid_scroll.dart'; import 'layout/layout.dart'; import 'layout/sizes.dart'; -import 'widgets/content/grid_row.dart'; +import 'widgets/row/grid_row.dart'; import 'widgets/footer/grid_footer.dart'; import 'widgets/header/grid_header.dart'; import 'widgets/toolbar/grid_toolbar.dart'; @@ -101,7 +101,7 @@ class _FlowyGridState extends State { controller: _scrollController.verticalController, slivers: [ _renderToolbar(gridId), - _renderHeader(gridId), + GridHeader(gridId: gridId, fields: List.from(state.fields)), _renderRows(context), const GridFooter(), ], @@ -144,21 +144,6 @@ class _FlowyGridState extends State { ); } - Widget _renderHeader(String gridId) { - return BlocBuilder( - buildWhen: (previous, current) => previous.fields.length != current.fields.length, - builder: (context, state) { - return GridHeader(gridId: gridId, fields: List.from(state.fields)); - - // return SliverPersistentHeader( - // delegate: GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)), - // floating: true, - // pinned: true, - // ); - }, - ); - } - Widget _renderRows(BuildContext context) { return BlocBuilder( buildWhen: (previous, current) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart similarity index 96% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 856338aea4..8a1b3a63ea 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -5,7 +5,7 @@ import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; import 'number_cell.dart'; -import 'selection_cell.dart'; +import 'selection_cell/selection_cell.dart'; import 'text_cell.dart'; Widget buildGridCell(String rowId, Field field, FutureCellData cellData) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_decoration.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_decoration.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_decoration.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_decoration.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart new file mode 100644 index 0000000000..7fc3b3246f --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart @@ -0,0 +1,7 @@ +export 'cell_builder.dart'; +export 'cell_container.dart'; +export 'text_cell.dart'; +export 'number_cell.dart'; +export 'date_cell.dart'; +export 'checkbox_cell.dart'; +export 'selection_cell/selection_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart new file mode 100644 index 0000000000..8f0f3dfc78 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart @@ -0,0 +1,77 @@ +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SelectionBadge extends StatelessWidget { + final SelectOption option; + const SelectionBadge({required this.option, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: option.color.make(context), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(6.0), + ), + child: FlowyText.medium(option.name, fontSize: 12), + ); + } +} + +extension SelectOptionColorExtension on SelectOptionColor { + Color make(BuildContext context) { + final theme = context.watch(); + switch (this) { + case SelectOptionColor.Purple: + return theme.tint1; + case SelectOptionColor.Pink: + return theme.tint2; + case SelectOptionColor.LightPink: + return theme.tint3; + case SelectOptionColor.Orange: + return theme.tint4; + case SelectOptionColor.Yellow: + return theme.tint5; + case SelectOptionColor.Lime: + return theme.tint6; + case SelectOptionColor.Green: + return theme.tint7; + case SelectOptionColor.Aqua: + return theme.tint8; + case SelectOptionColor.Blue: + return theme.tint9; + default: + throw ArgumentError; + } + } + + String optionName() { + switch (this) { + case SelectOptionColor.Purple: + return LocaleKeys.grid_selectOption_purpleColor.tr(); + case SelectOptionColor.Pink: + return LocaleKeys.grid_selectOption_pinkColor.tr(); + case SelectOptionColor.LightPink: + return LocaleKeys.grid_selectOption_lightPinkColor.tr(); + case SelectOptionColor.Orange: + return LocaleKeys.grid_selectOption_orangeColor.tr(); + case SelectOptionColor.Yellow: + return LocaleKeys.grid_selectOption_yellowColor.tr(); + case SelectOptionColor.Lime: + return LocaleKeys.grid_selectOption_limeColor.tr(); + case SelectOptionColor.Green: + return LocaleKeys.grid_selectOption_greenColor.tr(); + case SelectOptionColor.Aqua: + return LocaleKeys.grid_selectOption_aquaColor.tr(); + case SelectOptionColor.Blue: + return LocaleKeys.grid_selectOption_blueColor.tr(); + default: + throw ArgumentError; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart new file mode 100644 index 0000000000..de25430066 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -0,0 +1,45 @@ +import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'selection.dart'; + +class SelectionEditor extends StatelessWidget { + final GridCellData cellData; + const SelectionEditor({required this.cellData, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => SelectionEditorBloc(gridId: cellData.gridId, field: cellData.field), + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } +} + +class _SelectionCell extends StatelessWidget { + final SelectOption option; + const _SelectionCell({required this.option, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return InkWell( + onTap: () {}, + child: FlowyHover( + config: HoverDisplayConfig(hoverColor: theme.hover), + builder: (_, onHover) { + return SelectionBadge(option: option); + }, + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index 6a2051318e..89cd0b60ff 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -49,7 +49,10 @@ class GridFieldCell extends StatelessWidget { void _showFieldEditor(BuildContext context) { FieldEditor( gridId: fieldCellContext.gridId, - fieldContextLoader: FieldContextLoaderAdaptor(fieldCellContext), + fieldContextLoader: FieldContextLoaderAdaptor( + gridId: fieldCellContext.gridId, + field: fieldCellContext.field, + ), ).show(context); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart index 4f133090de..a69575a409 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/edit_option_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -183,56 +184,3 @@ class _SelectOptionColorCell extends StatelessWidget { ); } } - -extension SelectOptionColorExtension on SelectOptionColor { - Color color(BuildContext context) { - final theme = context.watch(); - switch (this) { - case SelectOptionColor.Purple: - return theme.tint1; - case SelectOptionColor.Pink: - return theme.tint2; - case SelectOptionColor.LightPink: - return theme.tint3; - case SelectOptionColor.Orange: - return theme.tint4; - case SelectOptionColor.Yellow: - return theme.tint5; - case SelectOptionColor.Lime: - return theme.tint6; - case SelectOptionColor.Green: - return theme.tint7; - case SelectOptionColor.Aqua: - return theme.tint8; - case SelectOptionColor.Blue: - return theme.tint9; - default: - throw ArgumentError; - } - } - - String optionName() { - switch (this) { - case SelectOptionColor.Purple: - return LocaleKeys.grid_selectOption_purpleColor.tr(); - case SelectOptionColor.Pink: - return LocaleKeys.grid_selectOption_pinkColor.tr(); - case SelectOptionColor.LightPink: - return LocaleKeys.grid_selectOption_lightPinkColor.tr(); - case SelectOptionColor.Orange: - return LocaleKeys.grid_selectOption_orangeColor.tr(); - case SelectOptionColor.Yellow: - return LocaleKeys.grid_selectOption_yellowColor.tr(); - case SelectOptionColor.Lime: - return LocaleKeys.grid_selectOption_limeColor.tr(); - case SelectOptionColor.Green: - return LocaleKeys.grid_selectOption_greenColor.tr(); - case SelectOptionColor.Aqua: - return LocaleKeys.grid_selectOption_aquaColor.tr(); - case SelectOptionColor.Blue: - return LocaleKeys.grid_selectOption_blueColor.tr(); - default: - throw ArgumentError; - } - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart similarity index 97% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 73594de957..c4c32bda3b 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -1,14 +1,13 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; -import 'cell_builder.dart'; -import 'cell_container.dart'; class GridRowWidget extends StatefulWidget { final GridRowData data; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index 9951e6ba65..a34682d204 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -97,14 +97,9 @@ class _GridPropertyCell extends StatelessWidget { hoverColor: theme.hover, leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), onTap: () { - final fieldCellContext = GridFieldCellContext( - gridId: gridId, - field: field, - ); - FieldEditor( gridId: gridId, - fieldContextLoader: FieldContextLoaderAdaptor(fieldCellContext), + fieldContextLoader: FieldContextLoaderAdaptor(gridId: gridId, field: field), ).show(context, anchorDirection: AnchorDirection.bottomRight); }, ), diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index c000793a5e..634de1b7f2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -11,17 +11,19 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); - static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock'); + static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock'); static const GridNotification DidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); static const GridNotification GridDidUpdateCells = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields'); + static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); static const $core.List values = [ Unknown, - GridDidCreateBlock, + DidCreateBlock, DidUpdateRow, GridDidUpdateCells, DidUpdateFields, + DidUpdateField, ]; static final $core.Map<$core.int, GridNotification> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 5dc1fbc1a5..571fe64399 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -13,12 +13,13 @@ const GridNotification$json = const { '1': 'GridNotification', '2': const [ const {'1': 'Unknown', '2': 0}, - const {'1': 'GridDidCreateBlock', '2': 11}, + const {'1': 'DidCreateBlock', '2': 11}, const {'1': 'DidUpdateRow', '2': 20}, const {'1': 'GridDidUpdateCells', '2': 30}, const {'1': 'DidUpdateFields', '2': 40}, + const {'1': 'DidUpdateField', '2': 41}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIQCgxEaWRVcGRhdGVSb3cQFBIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQHhITCg9EaWRVcGRhdGVGaWVsZHMQKA=='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhAKDERpZFVwZGF0ZVJvdxAUEhYKEkdyaWREaWRVcGRhdGVDZWxscxAeEhMKD0RpZFVwZGF0ZUZpZWxkcxAoEhIKDkRpZFVwZGF0ZUZpZWxkECk='); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 34c972a9bb..364c42f680 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -5,13 +5,11 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; #[derive(ProtoBuf_Enum, Debug)] pub enum GridNotification { Unknown = 0, - - GridDidCreateBlock = 11, - + DidCreateBlock = 11, DidUpdateRow = 20, - GridDidUpdateCells = 30, DidUpdateFields = 40, + DidUpdateField = 41, } impl std::default::Default for GridNotification { diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 0dd067b3d5..32e697b36e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -26,10 +26,11 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridNotification { Unknown = 0, - GridDidCreateBlock = 11, + DidCreateBlock = 11, DidUpdateRow = 20, GridDidUpdateCells = 30, DidUpdateFields = 40, + DidUpdateField = 41, } impl ::protobuf::ProtobufEnum for GridNotification { @@ -40,10 +41,11 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), - 11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock), + 11 => ::std::option::Option::Some(GridNotification::DidCreateBlock), 20 => ::std::option::Option::Some(GridNotification::DidUpdateRow), 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), 40 => ::std::option::Option::Some(GridNotification::DidUpdateFields), + 41 => ::std::option::Option::Some(GridNotification::DidUpdateField), _ => ::std::option::Option::None } } @@ -51,10 +53,11 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn values() -> &'static [Self] { static values: &'static [GridNotification] = &[ GridNotification::Unknown, - GridNotification::GridDidCreateBlock, + GridNotification::DidCreateBlock, GridNotification::DidUpdateRow, GridNotification::GridDidUpdateCells, GridNotification::DidUpdateFields, + GridNotification::DidUpdateField, ]; values } @@ -83,10 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*v\n\x10GridNotification\x12\x0b\n\x07Unkno\ - wn\x10\0\x12\x16\n\x12GridDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUpdateR\ - ow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDidUpdat\ - eFields\x10(b\x06proto3\ + \n\x17dart_notification.proto*\x86\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUp\ + dateRow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDid\ + UpdateFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index da1d193b21..176e0d83a4 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -2,8 +2,9 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; - GridDidCreateBlock = 11; + DidCreateBlock = 11; DidUpdateRow = 20; GridDidUpdateCells = 30; DidUpdateFields = 40; + DidUpdateField = 41; } 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 95c23f489b..443c1ee2bf 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -97,6 +97,7 @@ impl ClientGridEditor { } pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { + let field_id = params.field_id.clone(); let deserializer = match self.pad.read().await.get_field(¶ms.field_id) { None => return Err(ErrorCode::FieldDoesNotExist.into()), Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()), @@ -104,6 +105,7 @@ impl ClientGridEditor { let _ = self.modify(|grid| Ok(grid.update_field(params, deserializer)?)).await?; let _ = self.notify_did_update_fields().await?; + let _ = self.notify_did_update_field(&field_id).await?; Ok(()) } @@ -133,6 +135,7 @@ impl ClientGridEditor { .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) .await?; let _ = self.notify_did_update_fields().await?; + let _ = self.notify_did_update_field(field_id).await?; Ok(()) } @@ -294,7 +297,19 @@ impl ClientGridEditor { } pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { - let mut field_metas = self.pad.read().await.get_field_metas(field_orders)?; + let expected_len = match field_orders.as_ref() { + None => 0, + Some(field_orders) => field_orders.len(), + }; + + let field_metas = self.pad.read().await.get_field_metas(field_orders)?; + debug_assert!(field_metas.len() == expected_len); + if field_metas.len() != expected_len { + tracing::error!( + "This is a bug. The len of the field_metas should equal to {}", + expected_len + ); + } // field_metas.retain(|field_meta| field_meta.visibility); Ok(field_metas) } @@ -368,6 +383,20 @@ impl ClientGridEditor { .send(); Ok(()) } + + async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { + let field_orders: RepeatedFieldOrder = vec![FieldOrder::from(field_id)].into(); + let mut field_metas = self.get_field_metas(Some(field_orders)).await?; + debug_assert!(field_metas.len() == 1); + + if let Some(field_meta) = field_metas.pop() { + send_dart_notification(&self.grid_id, GridNotification::DidUpdateField) + .payload(field_meta) + .send(); + } + + Ok(()) + } } #[cfg(feature = "flowy_unit_test")] 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 b60aafedae..1dd2220f13 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -100,6 +100,12 @@ impl std::convert::From<&FieldMeta> for FieldOrder { } } +impl std::convert::From<&str> for FieldOrder { + fn from(s: &str) -> Self { + FieldOrder { field_id: s.to_owned() } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct GetEditFieldContextPayload { #[pb(index = 1)] @@ -193,6 +199,12 @@ impl std::ops::Deref for RepeatedFieldOrder { } } +impl std::convert::From> for RepeatedFieldOrder { + fn from(field_orders: Vec) -> Self { + RepeatedFieldOrder { items: field_orders } + } +} + #[derive(Debug, Default, Clone, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] From 1abf0b565f2191416bbf16199f100f350145c97e Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 4 Apr 2022 11:10:41 +0800 Subject: [PATCH 093/179] chore: cell highlight --- .../app_flowy/assets/translations/en.json | 3 +- .../grid/src/widgets/cell/cell_container.dart | 95 +++++++++++---- .../{selection.dart => extension.dart} | 112 +++++++++++++++--- .../cell/selection_cell/selection_cell.dart | 14 ++- .../cell/selection_cell/selection_editor.dart | 94 ++++++++++++++- .../grid/src/widgets/cell/text_cell.dart | 46 +++---- .../grid/src/widgets/header/grid_header.dart | 37 +++--- .../type_option/edit_option_pannel.dart | 4 +- frontend/app_flowy/pubspec.lock | 7 ++ frontend/app_flowy/pubspec.yaml | 2 +- .../flowy-grid/src/services/grid_editor.rs | 4 +- 11 files changed, 321 insertions(+), 97 deletions(-) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/{selection.dart => extension.dart} (52%) diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 9d73711cc7..55e57dfdc7 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -185,7 +185,8 @@ "aquaColor": "Aqua", "blueColor": "Blue", "deleteTag": "Delete tag", - "colorPannelTitle": "Colors" + "colorPannelTitle": "Colors", + "pannelTitle": "Select an option" } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index 0bfcc10caa..8890dc7576 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -1,9 +1,23 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; -class CellContainer extends StatefulWidget { +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; + +class CellStateNotifier extends ChangeNotifier { + bool _isFocus = false; + + set isFocus(bool value) { + if (_isFocus != value) { + _isFocus = value; + notifyListeners(); + } + } + + bool get isFocus => _isFocus; +} + +class CellContainer extends StatelessWidget { final Widget child; final double width; const CellContainer({ @@ -12,28 +26,65 @@ class CellContainer extends StatefulWidget { required this.width, }) : super(key: key); - @override - State createState() => _CellContainerState(); -} - -class _CellContainerState extends State { @override Widget build(BuildContext context) { - final theme = context.watch(); - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () {}, - child: Container( - constraints: BoxConstraints( - maxWidth: widget.width, - ), - decoration: BoxDecoration( - border: Border(right: borderSide, bottom: borderSide), - ), - padding: GridSize.cellContentInsets, - child: Center(child: IntrinsicHeight(child: widget.child)), + return ChangeNotifierProvider( + create: (_) => CellStateNotifier(), + child: Consumer( + builder: (context, state, _) { + return Container( + constraints: BoxConstraints( + maxWidth: width, + ), + decoration: _makeBoxDecoration(context, state), + padding: GridSize.cellContentInsets, + child: Center(child: IntrinsicHeight(child: child)), + ); + }, ), ); } + + BoxDecoration _makeBoxDecoration(BuildContext context, CellStateNotifier state) { + final theme = context.watch(); + if (state.isFocus) { + final borderSide = BorderSide(color: theme.main1, width: 1.0); + return BoxDecoration(border: Border.fromBorderSide(borderSide)); + } else { + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return BoxDecoration(border: Border(right: borderSide, bottom: borderSide)); + } + } +} + +abstract class GridCell extends StatefulWidget { + const GridCell({Key? key}) : super(key: key); + + void setFocus(BuildContext context, bool value) { + Provider.of(context, listen: false).isFocus = value; + } +} + +class CellFocusNode extends FocusNode { + VoidCallback? focusCallback; + + void addCallback(BuildContext context, VoidCallback callback) { + if (focusCallback != null) { + removeListener(focusCallback!); + } + focusCallback = () { + Provider.of(context, listen: false).isFocus = hasFocus; + callback(); + }; + + addListener(focusCallback!); + } + + @override + void dispose() { + if (focusCallback != null) { + removeListener(focusCallback!); + } + super.dispose(); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart similarity index 52% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index 8f0f3dfc78..7bf977d6a4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -5,23 +5,7 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - -class SelectionBadge extends StatelessWidget { - final SelectOption option; - const SelectionBadge({required this.option, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: option.color.make(context), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(6.0), - ), - child: FlowyText.medium(option.name, fontSize: 12), - ); - } -} +import 'package:textfield_tags/textfield_tags.dart'; extension SelectOptionColorExtension on SelectOptionColor { Color make(BuildContext context) { @@ -75,3 +59,97 @@ extension SelectOptionColorExtension on SelectOptionColor { } } } + +class SelectOptionTextField extends StatelessWidget { + final TextEditingController _controller; + final FocusNode _focusNode; + + SelectOptionTextField({ + TextEditingController? controller, + FocusNode? focusNode, + Key? key, + }) : _controller = controller ?? TextEditingController(), + _focusNode = focusNode ?? FocusNode(), + super(key: key); + + @override + Widget build(BuildContext context) { + return TextFieldTags( + textEditingController: _controller, + initialTags: ["abc", "bdf"], + focusNode: _focusNode, + textSeparators: const [' ', ','], + inputfieldBuilder: ( + BuildContext context, + TextEditingController editController, + FocusNode focusNode, + String? error, + void Function(String)? onChanged, + void Function(String)? onSubmitted, + ) { + return ((context, sc, tags, onTagDelegate) { + return TextField( + controller: editController, + focusNode: focusNode, + onChanged: (value) {}, + onEditingComplete: () => focusNode.unfocus(), + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + prefixIcon: _renderTags(tags, sc), + ), + ); + }); + }, + ); + } + + Widget? _renderTags(List tags, ScrollController sc) { + if (tags.isEmpty) { + return null; + } + + return SingleChildScrollView( + controller: sc, + scrollDirection: Axis.horizontal, + child: Row(children: [ + Container( + decoration: BoxDecoration( + color: Color.fromARGB(255, 74, 137, 92), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(6.0), + ), + child: FlowyText.medium("efc", fontSize: 12), + ), + Container( + decoration: BoxDecoration( + color: Color.fromARGB(255, 74, 137, 92), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(6.0), + ), + child: FlowyText.medium("abc", fontSize: 12), + ) + ]), + ); + } +} + +class SelectionBadge extends StatelessWidget { + final SelectOption option; + const SelectionBadge({required this.option, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: option.color.make(context), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(6.0), + ), + child: FlowyText.medium(option.name, fontSize: 12), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 0b1b1828f3..8e7c59b02c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -1,7 +1,10 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; import 'package:flutter/material.dart'; +import 'extension.dart'; + class SingleSelectCell extends StatefulWidget { final FutureCellData cellData; @@ -15,22 +18,31 @@ class SingleSelectCell extends StatefulWidget { } class _SingleSelectCellState extends State { + late CellFocusNode _focusNode; late SelectionCellBloc _cellBloc; + late TextEditingController _controller; @override void initState() { _cellBloc = getIt(param1: widget.cellData); + _controller = TextEditingController(); + _focusNode = CellFocusNode(); super.initState(); } @override Widget build(BuildContext context) { - return Container(); + _focusNode.addCallback(context, () {}); + return SelectOptionTextField( + focusNode: _focusNode, + controller: _controller, + ); } @override Future dispose() async { _cellBloc.close(); + _focusNode.dispose(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index de25430066..98e1774425 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -1,37 +1,108 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; -import 'selection.dart'; +import 'extension.dart'; class SelectionEditor extends StatelessWidget { final GridCellData cellData; const SelectionEditor({required this.cellData, Key? key}) : super(key: key); + void show(BuildContext context) { + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: this, + constraints: BoxConstraints.loose(const Size(240, 200)), + ), + identifier: toString(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomWithLeftAligned, + ); + } + @override Widget build(BuildContext context) { return BlocProvider( create: (context) => SelectionEditorBloc(gridId: cellData.gridId, field: cellData.field), child: BlocBuilder( builder: (context, state) { - return Container(); + return Column( + children: const [ + _Title(), + VSpace(10), + _OptionList(), + ], + ); }, ), ); } } +class _OptionList extends StatelessWidget { + const _OptionList({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final cells = state.options.map((option) => _SelectionCell(option)).toList(); + final list = ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + itemCount: cells.length, + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + ); + return list; + }, + ); + } +} + +class _Title extends StatelessWidget { + const _Title({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyText.medium(LocaleKeys.grid_selectOption_pannelTitle.tr(), fontSize: 12), + ); + } +} + class _SelectionCell extends StatelessWidget { final SelectOption option; - const _SelectionCell({required this.option, Key? key}) : super(key: key); + const _SelectionCell(this.option, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); + + // return FlowyButton( + // text: FlowyText.medium(fieldType.title(), fontSize: 12), + // hoverColor: theme.hover, + // onTap: () => onSelectField(fieldType), + // leftIcon: svgWidget(fieldType.iconName(), color: theme.iconColor), + // ); + return InkWell( onTap: () {}, child: FlowyHover( @@ -43,3 +114,20 @@ class _SelectionCell extends StatelessWidget { ); } } + +class SelectionBadge extends StatelessWidget { + final SelectOption option; + const SelectionBadge({required this.option, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: option.color.make(context), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(6.0), + ), + child: FlowyText.medium(option.name, fontSize: 12), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index e8c571bded..c4e272aeb4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -1,13 +1,11 @@ import 'dart:async'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'cell_container.dart'; -/// The interface of base cell. - -class GridTextCell extends StatefulWidget { +class GridTextCell extends GridCell { final FutureCellData cellData; const GridTextCell({ required this.cellData, @@ -19,21 +17,23 @@ class GridTextCell extends StatefulWidget { } class _GridTextCellState extends State { - late TextEditingController _controller; - Timer? _delayOperation; - final _focusNode = FocusNode(); late TextCellBloc _cellBloc; + late TextEditingController _controller; + late CellFocusNode _focusNode; + Timer? _delayOperation; @override void initState() { _cellBloc = getIt(param1: widget.cellData); _controller = TextEditingController(text: _cellBloc.state.content); - _focusNode.addListener(save); + _focusNode = CellFocusNode(); super.initState(); } @override Widget build(BuildContext context) { + _focusNode.addCallback(context, focusChanged); + return BlocProvider.value( value: _cellBloc, child: BlocConsumer( @@ -46,16 +46,8 @@ class _GridTextCellState extends State { return TextField( controller: _controller, focusNode: _focusNode, - onChanged: (value) { - Log.info("On change"); - save(); - }, - onEditingComplete: () { - Log.info("On complete"); - }, - onSubmitted: (value) { - Log.info("On submit"); - }, + onChanged: (value) => focusChanged(), + onEditingComplete: () => _focusNode.unfocus(), maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), decoration: const InputDecoration( @@ -72,18 +64,18 @@ class _GridTextCellState extends State { @override Future dispose() async { _cellBloc.close(); - _focusNode.removeListener(save); _focusNode.dispose(); super.dispose(); } - Future save() async { - _delayOperation?.cancel(); - _delayOperation = Timer(const Duration(milliseconds: 300), () { - if (_cellBloc.isClosed == false) { - _cellBloc.add(TextCellEvent.updateText(_controller.text)); - } - }); - // and later, before the timer goes off... + Future focusChanged() async { + if (mounted) { + _delayOperation?.cancel(); + _delayOperation = Timer(const Duration(milliseconds: 300), () { + if (_cellBloc.isClosed == false) { + _cellBloc.add(TextCellEvent.updateText(_controller.text)); + } + }); + } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 80a7a51d59..2a7baaa773 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -46,7 +46,7 @@ class _GridHeaderDelegate extends SliverPersistentHeaderDelegate { @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return _GridHeaderWidget(gridId: gridId, fields: fields, key: ObjectKey(fields)); + return _GridHeaderWidget(gridId: gridId, fields: fields); } @override @@ -73,27 +73,22 @@ class _GridHeaderWidget extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); - return BlocBuilder( - builder: (context, state) { - final cells = state.fields.map( - (field) => GridFieldCell( - GridFieldCellContext(gridId: gridId, field: field), - ), - ); - - final row = Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _HeaderLeading(), - ...cells, - _HeaderTrailing(gridId: gridId), - ], - key: UniqueKey(), - ); - - return Container(height: GridSize.headerHeight, color: theme.surface, child: row); - }, + final cells = fields.map( + (field) => GridFieldCell( + GridFieldCellContext(gridId: gridId, field: field), + ), ); + + final row = Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _HeaderLeading(), + ...cells, + _HeaderTrailing(gridId: gridId), + ], + ); + + return Container(height: GridSize.headerHeight, color: theme.surface, child: row); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart index a69575a409..1893a77846 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/edit_option_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -164,7 +164,7 @@ class _SelectOptionColorCell extends StatelessWidget { dimension: 16, child: Container( decoration: BoxDecoration( - color: color.color(context), + color: color.make(context), shape: BoxShape.circle, ), ), diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index abd76b4448..90e6dda24c 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -1148,6 +1148,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.11" + textfield_tags: + dependency: "direct main" + description: + name: textfield_tags + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" textstyle_extensions: dependency: transitive description: diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index ad1f6cd0e2..4d8ec095d5 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -67,7 +67,7 @@ dependencies: clipboard: ^0.1.3 connectivity_plus: 2.2.0 easy_localization: ^3.0.0 - + textfield_tags: ^2.0.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 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 443c1ee2bf..59840d1e4f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -303,12 +303,12 @@ impl ClientGridEditor { }; let field_metas = self.pad.read().await.get_field_metas(field_orders)?; - debug_assert!(field_metas.len() == expected_len); - if field_metas.len() != expected_len { + if expected_len != 0 && field_metas.len() != expected_len { tracing::error!( "This is a bug. The len of the field_metas should equal to {}", expected_len ); + debug_assert!(field_metas.len() == expected_len); } // field_metas.retain(|field_meta| field_meta.visibility); Ok(field_metas) From 271a8485b6fc5eecb7aadc1f66b835217d4eba96 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 4 Apr 2022 14:37:08 +0800 Subject: [PATCH 094/179] chore: selection text field --- .../grid/cell_bloc/selection_cell_bloc.dart | 8 +++--- .../grid/cell_bloc/text_cell_bloc.dart | 22 +++++++--------- .../application/grid/row/row_bloc.dart | 26 ++++++++++--------- .../application/grid/row/row_service.dart | 2 +- .../grid/src/widgets/cell/cell_builder.dart | 10 +++---- .../cell/selection_cell/extension.dart | 14 ++++------ .../cell/selection_cell/selection_cell.dart | 19 +++++++++++--- .../cell/selection_cell/selection_editor.dart | 17 ------------ .../grid/src/widgets/row/grid_row.dart | 24 +++++++++-------- 9 files changed, 66 insertions(+), 76 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 917e848a78..7c1358bced 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -36,9 +37,10 @@ class SelectionCellEvent with _$SelectionCellEvent { @freezed class SelectionCellState with _$SelectionCellState { - const factory SelectionCellState({ - Cell? cell, - }) = _SelectionCellState; + const factory SelectionCellState() = _SelectionCellState; + // required String girdId, + // required Field field, + // required List options, factory SelectionCellState.initial() => const SelectionCellState(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 985fad03be..f2162d8851 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -33,17 +33,15 @@ class TextCellBloc extends Bloc { } void updateCellContent(String content) { - if (state.cellData != null) { - final fieldId = state.cellData!.field.id; - final gridId = state.cellData!.gridId; - final rowId = state.cellData!.rowId; - service.updateCell( - data: content, - fieldId: fieldId, - gridId: gridId, - rowId: rowId, - ); - } + final fieldId = state.cellData.field.id; + final gridId = state.cellData.gridId; + final rowId = state.cellData.rowId; + service.updateCell( + data: content, + fieldId: fieldId, + gridId: gridId, + rowId: rowId, + ); } @override @@ -67,7 +65,7 @@ class TextCellState with _$TextCellState { }) = _TextCellState; factory TextCellState.initial(FutureCellData cellData) => TextCellState( - content: cellData?.cell?.content ?? "", + content: cellData.cell?.content ?? "", cellData: cellData, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 6fc7221a76..85e5c35650 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -13,7 +13,7 @@ import 'package:dartz/dartz.dart'; part 'row_bloc.freezed.dart'; -typedef CellDataMap = HashMap; +typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { final RowService rowService; @@ -48,10 +48,10 @@ class RowBloc extends Bloc { didUpdateCell: (_DidUpdateCell value) async { final optionRow = await state.row; final CellDataMap cellDataMap = optionRow.fold( - () => HashMap.identity(), + () => CellDataMap.identity(), (row) => _makeCellDatas(row), ); - emit(state.copyWith(cellDataMap: cellDataMap)); + emit(state.copyWith(cellDataMap: Some(cellDataMap))); }, ); }, @@ -111,13 +111,15 @@ class RowBloc extends Bloc { CellDataMap _makeCellDatas(Row row) { var map = CellDataMap.new(); for (final field in state.fields) { - map[field.id] = GridCellData( - rowId: row.id, - gridId: rowService.gridId, - blockId: rowService.blockId, - cell: row.cellByFieldId[field.id], - field: field, - ); + if (field.visibility) { + map[field.id] = GridCellData( + rowId: row.id, + gridId: rowService.gridId, + blockId: rowService.blockId, + cell: row.cellByFieldId[field.id], + field: field, + ); + } } return map; } @@ -138,7 +140,7 @@ class RowState with _$RowState { required double rowHeight, required List fields, required Future> row, - required CellDataMap? cellDataMap, + required Option cellDataMap, }) = _RowState; factory RowState.initial(GridRowData data) => RowState( @@ -146,6 +148,6 @@ class RowState with _$RowState { rowHeight: data.height, fields: data.fields, row: Future(() => none()), - cellDataMap: null, + cellDataMap: none(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index d30a22b7d0..1ef7b58d4b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -29,7 +29,7 @@ class RowService { } } -typedef FutureCellData = GridCellData?; +typedef FutureCellData = GridCellData; class GridCellData extends Equatable { final String gridId; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 8a1b3a63ea..178a44f9d7 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -1,5 +1,4 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -8,12 +7,9 @@ import 'number_cell.dart'; import 'selection_cell/selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(String rowId, Field field, FutureCellData cellData) { - if (cellData == null) { - return const SizedBox(); - } - final key = ValueKey(field.id + rowId); - switch (field.fieldType) { +Widget buildGridCell(FutureCellData cellData) { + final key = ValueKey(cellData.field.id + cellData.rowId); + switch (cellData.field.fieldType) { case FieldType.Checkbox: return CheckboxCell(cellData: cellData, key: key); case FieldType.DateTime: diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index 7bf977d6a4..7d5793f768 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -79,19 +79,13 @@ class SelectOptionTextField extends StatelessWidget { initialTags: ["abc", "bdf"], focusNode: _focusNode, textSeparators: const [' ', ','], - inputfieldBuilder: ( - BuildContext context, - TextEditingController editController, - FocusNode focusNode, - String? error, - void Function(String)? onChanged, - void Function(String)? onSubmitted, - ) { + inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) { return ((context, sc, tags, onTagDelegate) { return TextField( controller: editController, focusNode: focusNode, - onChanged: (value) {}, + onChanged: onChanged, + onSubmitted: onSubmitted, onEditingComplete: () => focusNode.unfocus(), maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), @@ -131,6 +125,8 @@ class SelectOptionTextField extends StatelessWidget { borderRadius: BorderRadius.circular(6.0), ), child: FlowyText.medium("abc", fontSize: 12), + margin: const EdgeInsets.symmetric(horizontal: 5.0), + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), ) ]), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 8e7c59b02c..5584b7ded5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -1,7 +1,9 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'extension.dart'; @@ -32,10 +34,19 @@ class _SingleSelectCellState extends State { @override Widget build(BuildContext context) { - _focusNode.addCallback(context, () {}); - return SelectOptionTextField( - focusNode: _focusNode, - controller: _controller, + _focusNode.addCallback(context, () { + Log.info(_focusNode.hasFocus); + }); + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return SelectOptionTextField( + focusNode: _focusNode, + controller: _controller, + ); + }, + ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 98e1774425..20e329c788 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -114,20 +114,3 @@ class _SelectionCell extends StatelessWidget { ); } } - -class SelectionBadge extends StatelessWidget { - final SelectOption option; - const SelectionBadge({required this.option, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: option.color.make(context), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(6.0), - ), - child: FlowyText.medium(option.name, fontSize: 12), - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index c4c32bda3b..06218f5776 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -122,17 +122,19 @@ class _RowCells extends StatelessWidget { return BlocBuilder( buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { - final children = state.fields - .where((field) => field.visibility) - .map((field) => CellContainer( - width: field.width.toDouble(), - child: buildGridCell( - state.rowId, - field, - state.cellDataMap?[field.id], - ), - )) - .toList(); + final List children = state.cellDataMap.fold( + () => [], + (dataMap) { + return dataMap.values.map( + (value) { + return CellContainer( + width: value.field.width.toDouble(), + child: buildGridCell(value), + ); + }, + ).toList(); + }, + ); return Row(children: children); }, From 5358203a46e0b95a627b03fda43a431fa3c8c87d Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 4 Apr 2022 20:47:04 +0800 Subject: [PATCH 095/179] chore: config option editor ui --- .../app_flowy/assets/translations/en.json | 3 +- .../app_flowy/lib/startup/deps_resolver.dart | 12 +- .../grid/cell_bloc/checkbox_cell_bloc.dart | 4 +- .../grid/cell_bloc/date_cell_bloc.dart | 2 +- .../grid/cell_bloc/number_cell_bloc.dart | 2 +- .../grid/cell_bloc/selection_cell_bloc.dart | 63 +++++- .../grid/cell_bloc/selection_editor_bloc.dart | 43 ++-- .../grid/cell_bloc/text_cell_bloc.dart | 8 +- .../workspace/application/grid/grid_bloc.dart | 8 +- .../application/grid/row/row_bloc.dart | 8 +- .../application/grid/row/row_service.dart | 6 +- .../plugins/grid/src/grid_page.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 13 +- .../grid/src/widgets/cell/cell_builder.dart | 2 +- .../grid/src/widgets/cell/cell_container.dart | 2 +- .../grid/src/widgets/cell/checkbox_cell.dart | 2 +- .../grid/src/widgets/cell/date_cell.dart | 2 +- .../grid/src/widgets/cell/number_cell.dart | 2 +- .../cell/selection_cell/extension.dart | 88 +++++---- .../cell/selection_cell/selection_cell.dart | 26 ++- .../cell/selection_cell/selection_editor.dart | 184 +++++++++++++----- .../grid/src/widgets/cell/text_cell.dart | 2 +- .../src/widgets/row/cell/number_cell.dart | 44 +++++ .../grid/src/widgets/row/grid_row.dart | 2 +- .../grid/src/widgets/row/number_cell.dart | 44 +++++ .../flowy_infra_ui/lib/style_widget/text.dart | 2 +- .../src/entities/meta.rs | 2 +- 27 files changed, 412 insertions(+), 166 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 55e57dfdc7..7e20a947dc 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -186,7 +186,8 @@ "blueColor": "Blue", "deleteTag": "Delete tag", "colorPannelTitle": "Colors", - "pannelTitle": "Select an option" + "pannelTitle": "Select an option or create one", + "searchOption": "Search for an option" } } } diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 9020101083..c23b259bfe 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -151,7 +151,7 @@ void _resolveGridDeps(GetIt getIt) { (view, _) => GridBloc(view: view, service: GridService()), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (data, _) => RowBloc( rowData: data, rowlistener: RowListener(rowId: data.rowId), @@ -179,35 +179,35 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => TextCellBloc( service: CellService(), cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => SelectionCellBloc( service: CellService(), cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => NumberCellBloc( service: CellService(), cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => DateCellBloc( service: CellService(), cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => CheckboxCellBloc( service: CellService(), cellData: cellData, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 3609f39de7..f5bc7e7c18 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -9,11 +9,11 @@ part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { final CellService service; - // final FutureCellData cellData; + // final CellData cellData; CheckboxCellBloc({ required this.service, - required FutureCellData cellData, + required CellData cellData, }) : super(CheckboxCellState.initial()) { on( (event, emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index 33829863dd..7a995aab28 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -9,7 +9,7 @@ part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { final CellService service; - final FutureCellData cellData; + final CellData cellData; DateCellBloc({ required this.service, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index 6e58d24a54..83d2eff57d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -12,7 +12,7 @@ class NumberCellBloc extends Bloc { NumberCellBloc({ required this.service, - required FutureCellData cellData, + required CellData cellData, }) : super(NumberCellState.initial()) { on( (event, emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 7c1358bced..2cde7c6a96 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,5 +1,7 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -13,12 +15,17 @@ class SelectionCellBloc extends Bloc { SelectionCellBloc({ required this.service, - required FutureCellData cellData, - }) : super(SelectionCellState.initial()) { + required CellData cellData, + }) : super(SelectionCellState.initial(cellData)) { on( (event, emit) async { await event.map( - initial: (_InitialCell value) async {}, + initial: (_InitialCell value) async { + _loadOptions(); + }, + didReceiveOptions: (_DidReceiveOptions value) { + emit(state.copyWith(options: value.options, selectedOptions: value.selectedOptions)); + }, ); }, ); @@ -28,19 +35,57 @@ class SelectionCellBloc extends Bloc { Future close() async { return super.close(); } + + void _loadOptions() async { + final result = await FieldContextLoaderAdaptor( + gridId: state.cellData.gridId, + field: state.cellData.field, + ).load(); + + result.fold( + (context) { + List options = []; + switch (state.cellData.field.fieldType) { + case FieldType.MultiSelect: + options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options); + break; + case FieldType.SingleSelect: + options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options); + break; + default: + Log.error("Invalid field type, expect single select or multiple select"); + break; + } + + final ids = state.cellData.cell?.content.split(','); + final selectedOptions = ids?.map((id) => options.firstWhere((option) => option.id == id)).toList() ?? []; + add(SelectionCellEvent.didReceiveOptions(options, selectedOptions)); + }, + (err) => Log.error(err), + ); + } } @freezed class SelectionCellEvent with _$SelectionCellEvent { const factory SelectionCellEvent.initial() = _InitialCell; + const factory SelectionCellEvent.didReceiveOptions( + List options, + List selectedOptions, + ) = _DidReceiveOptions; } @freezed class SelectionCellState with _$SelectionCellState { - const factory SelectionCellState() = _SelectionCellState; - // required String girdId, - // required Field field, - // required List options, + const factory SelectionCellState({ + required CellData cellData, + required List options, + required List selectedOptions, + }) = _SelectionCellState; - factory SelectionCellState.initial() => const SelectionCellState(); + factory SelectionCellState.initial(CellData cellData) => SelectionCellState( + cellData: cellData, + options: [], + selectedOptions: [], + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 7e617069c4..e2109a4c57 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -11,16 +11,18 @@ import 'cell_service.dart'; part 'selection_editor_bloc.freezed.dart'; -class SelectionEditorBloc extends Bloc { +class SelectOptionEditorBloc extends Bloc { final CellService service = CellService(); final FieldListener _listener; - SelectionEditorBloc({ + SelectOptionEditorBloc({ required String gridId, required Field field, + required List options, + required List selectedOptions, }) : _listener = FieldListener(fieldId: field.id), - super(SelectionEditorState.initial(gridId, field)) { - on( + super(SelectOptionEditorState.initial(gridId, field, options, selectedOptions)) { + on( (event, emit) async { await event.map( initial: (_Initial value) async { @@ -34,6 +36,7 @@ class SelectionEditorBloc extends Bloc add(SelectionEditorEvent.didReceiveFieldUpdate(field)), + (field) => add(SelectOptionEditorEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); }); @@ -70,7 +73,7 @@ class SelectionEditorBloc extends Bloc Log.error(err), ); @@ -78,25 +81,33 @@ class SelectionEditorBloc extends Bloc options) = _DidReceiveOptions; +class SelectOptionEditorEvent with _$SelectOptionEditorEvent { + const factory SelectOptionEditorEvent.initial() = _Initial; + const factory SelectOptionEditorEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate; + const factory SelectOptionEditorEvent.didReceiveOptions(List options) = _DidReceiveOptions; + const factory SelectOptionEditorEvent.newOption(String optionName) = _newOption; } @freezed -class SelectionEditorState with _$SelectionEditorState { - const factory SelectionEditorState({ +class SelectOptionEditorState with _$SelectOptionEditorState { + const factory SelectOptionEditorState({ required String gridId, required Field field, required List options, - }) = _SelectionEditorState; + required List selectedOptions, + }) = _SelectOptionEditorState; - factory SelectionEditorState.initial(String gridId, Field field) { - return SelectionEditorState( + factory SelectOptionEditorState.initial( + String gridId, + Field field, + List options, + List selectedOptions, + ) { + return SelectOptionEditorState( gridId: gridId, field: field, - options: [], + options: options, + selectedOptions: selectedOptions, ); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index f2162d8851..5af39bbd9f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -11,7 +11,7 @@ class TextCellBloc extends Bloc { TextCellBloc({ required this.service, - required FutureCellData cellData, + required CellData cellData, }) : super(TextCellState.initial(cellData)) { on( (event, emit) async { @@ -53,7 +53,7 @@ class TextCellBloc extends Bloc { @freezed class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; - const factory TextCellEvent.didReceiveCellData(GridCellData cellData) = _DidReceiveCellData; + const factory TextCellEvent.didReceiveCellData(CellData cellData) = _DidReceiveCellData; const factory TextCellEvent.updateText(String text) = _UpdateText; } @@ -61,10 +61,10 @@ class TextCellEvent with _$TextCellEvent { class TextCellState with _$TextCellState { const factory TextCellState({ required String content, - required FutureCellData cellData, + required CellData cellData, }) = _TextCellState; - factory TextCellState.initial(FutureCellData cellData) => TextCellState( + factory TextCellState.initial(CellData cellData) => TextCellState( content: cellData.cell?.content ?? "", cellData: cellData, ); 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 00f90e0bfc..4b63ec0251 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -169,14 +169,14 @@ class GridBlockRow { }); } -class GridRowData extends Equatable { +class RowData extends Equatable { final String gridId; final String rowId; final String blockId; final List fields; final double height; - const GridRowData({ + const RowData({ required this.gridId, required this.rowId, required this.blockId, @@ -184,8 +184,8 @@ class GridRowData extends Equatable { required this.height, }); - factory GridRowData.fromBlockRow(GridBlockRow row, List fields) { - return GridRowData( + factory RowData.fromBlockRow(GridBlockRow row, List fields) { + return RowData( gridId: row.gridId, rowId: row.rowId, blockId: row.blockId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 85e5c35650..14f30b4359 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -13,14 +13,14 @@ import 'package:dartz/dartz.dart'; part 'row_bloc.freezed.dart'; -typedef CellDataMap = LinkedHashMap; +typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { final RowService rowService; final RowListener rowlistener; final GridFieldsListener fieldListener; - RowBloc({required GridRowData rowData, required this.rowlistener}) + RowBloc({required RowData rowData, required this.rowlistener}) : rowService = RowService( gridId: rowData.gridId, blockId: rowData.blockId, @@ -112,7 +112,7 @@ class RowBloc extends Bloc { var map = CellDataMap.new(); for (final field in state.fields) { if (field.visibility) { - map[field.id] = GridCellData( + map[field.id] = CellData( rowId: row.id, gridId: rowService.gridId, blockId: rowService.blockId, @@ -143,7 +143,7 @@ class RowState with _$RowState { required Option cellDataMap, }) = _RowState; - factory RowState.initial(GridRowData data) => RowState( + factory RowState.initial(RowData data) => RowState( rowId: data.rowId, rowHeight: data.height, fields: data.fields, diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 1ef7b58d4b..a65cb81b29 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -29,16 +29,14 @@ class RowService { } } -typedef FutureCellData = GridCellData; - -class GridCellData extends Equatable { +class CellData extends Equatable { final String gridId; final String rowId; final String blockId; final Field field; final Cell? cell; - const GridCellData({ + const CellData({ required this.rowId, required this.gridId, required this.blockId, 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 111235841f..936ad68c44 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 @@ -157,7 +157,7 @@ class _FlowyGridState extends State { (context, index) { final blockRow = context.read().state.rows[index]; final fields = context.read().state.fields; - final rowData = GridRowData.fromBlockRow(blockRow, fields); + final rowData = RowData.fromBlockRow(blockRow, fields); return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)); }, childCount: context.read().state.rows.length, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index c24bdb4326..23a541e610 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -9,8 +9,9 @@ class GridSize { static double get leadingHeaderPadding => 30 * scale; static double get trailHeaderPadding => 140 * scale; static double get headerContainerPadding => 0 * scale; - static double get cellContentPadding => 10 * scale; - static double get typeOptionItemHeight => 30 * scale; + static double get cellHPadding => 10 * scale; + static double get cellVPadding => 8 * scale; + static double get typeOptionItemHeight => 32 * scale; static double get typeOptionSeparatorHeight => 6 * scale; // @@ -19,13 +20,13 @@ class GridSize { vertical: GridSize.headerContainerPadding, ); static EdgeInsets get cellContentInsets => EdgeInsets.symmetric( - horizontal: GridSize.cellContentPadding, - vertical: GridSize.cellContentPadding, + horizontal: GridSize.cellHPadding, + vertical: GridSize.cellVPadding, ); static EdgeInsets get fieldContentInsets => EdgeInsets.symmetric( - horizontal: GridSize.cellContentPadding, - vertical: GridSize.cellContentPadding, + horizontal: GridSize.cellHPadding, + vertical: GridSize.cellVPadding, ); static EdgeInsets get typeOptionContentInsets => const EdgeInsets.symmetric( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 178a44f9d7..3b84ac557a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -7,7 +7,7 @@ import 'number_cell.dart'; import 'selection_cell/selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(FutureCellData cellData) { +Widget buildGridCell(CellData cellData) { final key = ValueKey(cellData.field.id + cellData.rowId); switch (cellData.field.fieldType) { case FieldType.Checkbox: diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index 8890dc7576..57f3610be2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -38,7 +38,7 @@ class CellContainer extends StatelessWidget { ), decoration: _makeBoxDecoration(context, state), padding: GridSize.cellContentInsets, - child: Center(child: IntrinsicHeight(child: child)), + child: Center(child: child), ); }, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index dc8f757e36..7e1fdf166a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final FutureCellData cellData; + final CellData cellData; const CheckboxCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index ec1babd799..e3b48279c0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateCell extends StatefulWidget { - final FutureCellData cellData; + final CellData cellData; const DateCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index bc51829412..41b8cf6ee5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final FutureCellData cellData; + final CellData cellData; const NumberCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index 7d5793f768..9a91999a9d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -1,3 +1,6 @@ +import 'dart:collection'; + +import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; @@ -61,10 +64,19 @@ extension SelectOptionColorExtension on SelectOptionColor { } class SelectOptionTextField extends StatelessWidget { - final TextEditingController _controller; final FocusNode _focusNode; + final TextEditingController _controller; + final TextfieldTagsController tagController; + final LinkedHashMap optionMap; + final double distanceToText; + + final Function(String) onNewTag; SelectOptionTextField({ + required this.optionMap, + required this.distanceToText, + required this.tagController, + required this.onNewTag, TextEditingController? controller, FocusNode? focusNode, Key? key, @@ -74,26 +86,45 @@ class SelectOptionTextField extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch(); + return TextFieldTags( textEditingController: _controller, - initialTags: ["abc", "bdf"], + textfieldTagsController: tagController, + initialTags: optionMap.keys.toList(), focusNode: _focusNode, textSeparators: const [' ', ','], inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) { return ((context, sc, tags, onTagDelegate) { + tags.retainWhere((name) => optionMap.containsKey(name) == false); + if (tags.isNotEmpty) { + assert(tags.length == 1); + onNewTag(tags.first); + } + return TextField( controller: editController, focusNode: focusNode, onChanged: onChanged, onSubmitted: onSubmitted, - onEditingComplete: () => focusNode.unfocus(), maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), decoration: InputDecoration( - contentPadding: EdgeInsets.zero, - border: InputBorder.none, + border: OutlineInputBorder( + borderSide: BorderSide(color: theme.shader3, width: 1.0), + borderRadius: Corners.s10Border, + ), isDense: true, - prefixIcon: _renderTags(tags, sc), + prefixIcon: _renderTags(sc), + hintText: LocaleKeys.grid_selectOption_searchOption.tr(), + prefixIconConstraints: BoxConstraints(maxWidth: distanceToText), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: theme.main1, + width: 1.0, + ), + borderRadius: Corners.s10Border, + ), ), ); }); @@ -101,41 +132,26 @@ class SelectOptionTextField extends StatelessWidget { ); } - Widget? _renderTags(List tags, ScrollController sc) { - if (tags.isEmpty) { + Widget? _renderTags(ScrollController sc) { + if (optionMap.isEmpty) { return null; } - return SingleChildScrollView( - controller: sc, - scrollDirection: Axis.horizontal, - child: Row(children: [ - Container( - decoration: BoxDecoration( - color: Color.fromARGB(255, 74, 137, 92), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(6.0), - ), - child: FlowyText.medium("efc", fontSize: 12), - ), - Container( - decoration: BoxDecoration( - color: Color.fromARGB(255, 74, 137, 92), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(6.0), - ), - child: FlowyText.medium("abc", fontSize: 12), - margin: const EdgeInsets.symmetric(horizontal: 5.0), - padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), - ) - ]), + final children = optionMap.values.map((option) => SelectOptionTag(option: option)).toList(); + return Padding( + padding: const EdgeInsets.all(8.0), + child: SingleChildScrollView( + controller: sc, + scrollDirection: Axis.horizontal, + child: Row(children: children), + ), ); } } -class SelectionBadge extends StatelessWidget { +class SelectOptionTag extends StatelessWidget { final SelectOption option; - const SelectionBadge({required this.option, Key? key}) : super(key: key); + const SelectOptionTag({required this.option, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -143,9 +159,11 @@ class SelectionBadge extends StatelessWidget { decoration: BoxDecoration( color: option.color.make(context), shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(6.0), + borderRadius: BorderRadius.circular(8.0), ), - child: FlowyText.medium(option.name, fontSize: 12), + child: Center(child: FlowyText.medium(option.name, fontSize: 12)), + margin: const EdgeInsets.symmetric(horizontal: 3.0), + padding: const EdgeInsets.symmetric(horizontal: 6.0), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 5584b7ded5..3fe1b19c14 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -6,9 +6,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'extension.dart'; +import 'selection_editor.dart'; class SingleSelectCell extends StatefulWidget { - final FutureCellData cellData; + final CellData cellData; const SingleSelectCell({ required this.cellData, @@ -20,30 +21,28 @@ class SingleSelectCell extends StatefulWidget { } class _SingleSelectCellState extends State { - late CellFocusNode _focusNode; late SelectionCellBloc _cellBloc; - late TextEditingController _controller; @override void initState() { - _cellBloc = getIt(param1: widget.cellData); - _controller = TextEditingController(); - _focusNode = CellFocusNode(); + _cellBloc = getIt(param1: widget.cellData)..add(const SelectionCellEvent.initial()); super.initState(); } @override Widget build(BuildContext context) { - _focusNode.addCallback(context, () { - Log.info(_focusNode.hasFocus); - }); return BlocProvider.value( value: _cellBloc, child: BlocBuilder( builder: (context, state) { - return SelectOptionTextField( - focusNode: _focusNode, - controller: _controller, + final children = state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList(); + return SizedBox.expand( + child: InkWell( + onTap: () { + SelectionEditor.show(context, state.cellData, state.options, state.selectedOptions); + }, + child: Row(children: children), + ), ); }, ), @@ -53,14 +52,13 @@ class _SingleSelectCellState extends State { @override Future dispose() async { _cellBloc.close(); - _focusNode.dispose(); super.dispose(); } } //---------------------------------------------------------------- class MultiSelectCell extends StatefulWidget { - final FutureCellData cellData; + final CellData cellData; const MultiSelectCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 20e329c788..0c8d207a4b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -1,6 +1,9 @@ +import 'dart:collection'; + import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; @@ -12,42 +15,81 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:textfield_tags/textfield_tags.dart'; import 'extension.dart'; -class SelectionEditor extends StatelessWidget { - final GridCellData cellData; - const SelectionEditor({required this.cellData, Key? key}) : super(key: key); +const double _editorPannelWidth = 300; - void show(BuildContext context) { - FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer( - child: this, - constraints: BoxConstraints.loose(const Size(240, 200)), - ), - identifier: toString(), - anchorContext: context, - anchorDirection: AnchorDirection.bottomWithLeftAligned, - ); +class SelectionEditor extends StatelessWidget { + final CellData cellData; + final List options; + final List selectedOptions; + + const SelectionEditor({ + required this.cellData, + required this.options, + required this.selectedOptions, + Key? key, + }) : super(key: key); + + static String identifier() { + return (SelectionEditor).toString(); } @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => SelectionEditorBloc(gridId: cellData.gridId, field: cellData.field), - child: BlocBuilder( + create: (context) => SelectOptionEditorBloc( + gridId: cellData.gridId, + field: cellData.field, + options: options, + selectedOptions: selectedOptions, + ), + child: BlocBuilder( builder: (context, state) { - return Column( - children: const [ - _Title(), - VSpace(10), - _OptionList(), + return CustomScrollView( + shrinkWrap: true, + slivers: [ + SliverToBoxAdapter(child: _TextField()), + const SliverToBoxAdapter(child: VSpace(10)), + const SliverToBoxAdapter(child: _Title()), + const SliverToBoxAdapter(child: _OptionList()), ], ); }, ), ); } + + static void show( + BuildContext context, + CellData cellData, + List options, + List selectedOptions, + ) { + SelectionEditor.hide(context); + final editor = SelectionEditor( + cellData: cellData, + options: options, + selectedOptions: selectedOptions, + ); + + // + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: SizedBox(width: _editorPannelWidth, child: editor), + constraints: BoxConstraints.loose(const Size(_editorPannelWidth, 300)), + ), + identifier: SelectionEditor.identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomWithCenterAligned, + ); + } + + static void hide(BuildContext context) { + FlowyOverlay.of(context).remove(identifier()); + } } class _OptionList extends StatelessWidget { @@ -55,9 +97,9 @@ class _OptionList extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( builder: (context, state) { - final cells = state.options.map((option) => _SelectionCell(option)).toList(); + final cells = state.options.map((option) => _SelectOptionCell(option)).toList(); final list = ListView.separated( shrinkWrap: true, controller: ScrollController(), @@ -76,40 +118,84 @@ class _OptionList extends StatelessWidget { } } +class _TextField extends StatelessWidget { + final TextfieldTagsController _tagController = TextfieldTagsController(); + + _TextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocConsumer( + listener: (context, state) {}, + buildWhen: (previous, current) => previous.field.id != current.field.id, + builder: (context, state) { + final optionMap = LinkedHashMap.fromIterable(state.selectedOptions, + key: (option) => option.name, value: (option) => option); + return SizedBox( + height: 42, + child: SelectOptionTextField( + optionMap: optionMap, + distanceToText: _editorPannelWidth * 0.7, + tagController: _tagController, + onNewTag: (newTagName) { + context.read().add(SelectOptionEditorEvent.newOption(newTagName)); + }, + ), + ); + }, + ); + } +} + class _Title extends StatelessWidget { const _Title({Key? key}) : super(key: key); @override Widget build(BuildContext context) { + final theme = context.watch(); return SizedBox( height: GridSize.typeOptionItemHeight, - child: FlowyText.medium(LocaleKeys.grid_selectOption_pannelTitle.tr(), fontSize: 12), - ); - } -} - -class _SelectionCell extends StatelessWidget { - final SelectOption option; - const _SelectionCell(this.option, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - - // return FlowyButton( - // text: FlowyText.medium(fieldType.title(), fontSize: 12), - // hoverColor: theme.hover, - // onTap: () => onSelectField(fieldType), - // leftIcon: svgWidget(fieldType.iconName(), color: theme.iconColor), - // ); - - return InkWell( - onTap: () {}, - child: FlowyHover( - config: HoverDisplayConfig(hoverColor: theme.hover), - builder: (_, onHover) { - return SelectionBadge(option: option); - }, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 6), + child: FlowyText.medium( + LocaleKeys.grid_selectOption_pannelTitle.tr(), + fontSize: 12, + color: theme.shader3, + ), + ), + ); + } +} + +class _SelectOptionCell extends StatelessWidget { + final SelectOption option; + const _SelectOptionCell(this.option, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: InkWell( + onTap: () {}, + child: FlowyHover( + config: HoverDisplayConfig(hoverColor: theme.hover), + builder: (_, onHover) { + List children = [ + SelectOptionTag(option: option), + const Spacer(), + ]; + + if (onHover) { + children.add(svgWidget("editor/details", color: theme.iconColor)); + } + + return Padding( + padding: const EdgeInsets.all(3.0), + child: Row(children: children), + ); + }, + ), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index c4e272aeb4..c7b4219bab 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -6,7 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_container.dart'; class GridTextCell extends GridCell { - final FutureCellData cellData; + final CellData cellData; const GridTextCell({ required this.cellData, Key? key, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart new file mode 100644 index 0000000000..41b8cf6ee5 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart @@ -0,0 +1,44 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class NumberCell extends StatefulWidget { + final CellData cellData; + + const NumberCell({ + required this.cellData, + Key? key, + }) : super(key: key); + + @override + State createState() => _NumberCellState(); +} + +class _NumberCellState extends State { + late NumberCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.cellData); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 06218f5776..5586328e32 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -10,7 +10,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; class GridRowWidget extends StatefulWidget { - final GridRowData data; + final RowData data; const GridRowWidget({required this.data, Key? key}) : super(key: key); @override diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart new file mode 100644 index 0000000000..41b8cf6ee5 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart @@ -0,0 +1,44 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class NumberCell extends StatefulWidget { + final CellData cellData; + + const NumberCell({ + required this.cellData, + Key? key, + }) : super(key: key); + + @override + State createState() => _NumberCellState(); +} + +class _NumberCellState extends State { + late NumberCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.cellData); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart index 7ddfdc1c13..55f29eba93 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart @@ -44,7 +44,7 @@ class FlowyText extends StatelessWidget { softWrap: false, textAlign: textAlign, style: TextStyle( - color: theme.textColor, + color: color ?? theme.textColor, fontWeight: fontWeight, fontSize: fontSize + 2, fontFamily: 'Mulish', diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index a543085a78..9be0faa99d 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; -pub const DEFAULT_ROW_HEIGHT: i32 = 36; +pub const DEFAULT_ROW_HEIGHT: i32 = 42; pub const DEFAULT_FIELD_WIDTH: i32 = 150; #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] From 99d827f07daa1c6e3ac8568aaf36c9145ee7eba6 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 5 Apr 2022 14:25:07 +0800 Subject: [PATCH 096/179] chore: update cell data --- .../grid/cell_bloc/selection_editor_bloc.dart | 39 +- .../dart_event/flowy-grid/dart_event.dart | 34 + .../flowy-error-code/code.pbenum.dart | 2 + .../flowy-error-code/code.pbjson.dart | 3 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 + .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../flowy-grid/selection_type_option.pb.dart | 164 +++++ .../selection_type_option.pbjson.dart | 28 + .../down.sql | 3 + .../up.sql | 7 + .../rust-lib/flowy-database/src/schema.rs | 8 + .../rust-lib/flowy-grid/src/event_handler.rs | 19 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 9 +- frontend/rust-lib/flowy-grid/src/manager.rs | 37 +- .../src/protobuf/model/event_map.rs | 13 +- .../protobuf/model/selection_type_option.rs | 596 +++++++++++++++++- .../src/protobuf/proto/event_map.proto | 2 + .../proto/selection_type_option.proto | 10 + .../src/services/block_meta_editor.rs | 94 ++- .../type_options/checkbox_type_option.rs | 6 +- .../field/type_options/date_type_option.rs | 6 +- .../field/type_options/number_type_option.rs | 6 +- .../type_options/selection_type_option.rs | 82 ++- .../field/type_options/text_type_option.rs | 6 +- .../flowy-grid/src/services/grid_editor.rs | 49 +- .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- .../src/services/persistence/block_index.rs | 49 ++ .../{kv_persistence.rs => persistence/kv.rs} | 9 +- .../src/services/persistence/mod.rs | 16 + ...l_data_serde.rs => cell_data_operation.rs} | 5 +- .../flowy-grid/src/services/row/mod.rs | 4 +- .../src/services/row/row_builder.rs | 1 + .../flowy-grid/src/services/row/row_loader.rs | 32 +- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../flowy-sdk/src/deps_resolve/grid_deps.rs | 16 +- shared-lib/flowy-error-code/src/code.rs | 2 + .../src/protobuf/model/code.rs | 14 +- .../src/protobuf/proto/code.proto | 1 + .../src/entities/grid.rs | 6 + .../src/entities/meta.rs | 14 +- .../src/client_grid/grid_meta_pad.rs | 3 +- 41 files changed, 1235 insertions(+), 172 deletions(-) create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/down.sql create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/up.sql create mode 100644 frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs rename frontend/rust-lib/flowy-grid/src/services/{kv_persistence.rs => persistence/kv.rs} (95%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/persistence/mod.rs rename frontend/rust-lib/flowy-grid/src/services/row/{cell_data_serde.rs => cell_data_operation.rs} (97%) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index e2109a4c57..5ce68105ea 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -1,5 +1,7 @@ import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; @@ -12,16 +14,18 @@ import 'cell_service.dart'; part 'selection_editor_bloc.freezed.dart'; class SelectOptionEditorBloc extends Bloc { - final CellService service = CellService(); + final TypeOptionService _typeOptionService; + final CellService _cellService; final FieldListener _listener; SelectOptionEditorBloc({ - required String gridId, - required Field field, + required CellData cellData, required List options, required List selectedOptions, - }) : _listener = FieldListener(fieldId: field.id), - super(SelectOptionEditorState.initial(gridId, field, options, selectedOptions)) { + }) : _cellService = CellService(), + _typeOptionService = TypeOptionService(fieldId: cellData.field.id), + _listener = FieldListener(fieldId: cellData.field.id), + super(SelectOptionEditorState.initial(cellData, options, selectedOptions)) { on( (event, emit) async { await event.map( @@ -36,7 +40,18 @@ class SelectOptionEditorBloc extends Bloc null, (err) => Log.error(err)); + }, + selectOption: (_SelectOption value) { + _cellService.updateCell( + gridId: state.gridId, + fieldId: state.fieldId, + rowId: state.rowId, + data: data, + ); + }, ); }, ); @@ -85,7 +100,8 @@ class SelectOptionEditorEvent with _$SelectOptionEditorEvent { const factory SelectOptionEditorEvent.initial() = _Initial; const factory SelectOptionEditorEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate; const factory SelectOptionEditorEvent.didReceiveOptions(List options) = _DidReceiveOptions; - const factory SelectOptionEditorEvent.newOption(String optionName) = _newOption; + const factory SelectOptionEditorEvent.newOption(String optionName) = _NewOption; + const factory SelectOptionEditorEvent.selectOption(String optionId) = _SelectOption; } @freezed @@ -93,19 +109,20 @@ class SelectOptionEditorState with _$SelectOptionEditorState { const factory SelectOptionEditorState({ required String gridId, required Field field, + required String rowId, required List options, required List selectedOptions, }) = _SelectOptionEditorState; factory SelectOptionEditorState.initial( - String gridId, - Field field, + CellData cellData, List options, List selectedOptions, ) { return SelectOptionEditorState( - gridId: gridId, - field: field, + gridId: cellData.gridId, + field: cellData.field, + rowId: cellData.rowId, options: options, selectedOptions: selectedOptions, ); 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 45b33f1004..a709d06fe8 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 @@ -171,6 +171,23 @@ class GridEventCreateSelectOption { } } +class GridEventGetSelectOptions { + FieldIdentifierPayload request; + GridEventGetSelectOptions(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetSelectOptions.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(SelectOptionContext.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateRow { CreateRowPayload request; GridEventCreateRow(this.request); @@ -222,3 +239,20 @@ class GridEventUpdateCell { } } +class GridEventInsertSelectOption { + InsertSelectOptionPayload request; + GridEventInsertSelectOption(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.InsertSelectOption.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-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index 9c4e31eeea..a638e65405 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -45,6 +45,7 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode GridIdIsEmpty = ErrorCode._(410, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridIdIsEmpty'); static const ErrorCode BlockIdIsEmpty = ErrorCode._(420, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty'); static const ErrorCode RowIdIsEmpty = ErrorCode._(430, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); + static const ErrorCode OptionIdIsEmpty = ErrorCode._(431, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OptionIdIsEmpty'); static const ErrorCode FieldIdIsEmpty = ErrorCode._(440, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldIdIsEmpty'); static const ErrorCode FieldDoesNotExist = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldDoesNotExist'); static const ErrorCode SelectOptionNameIsEmpty = ErrorCode._(442, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SelectOptionNameIsEmpty'); @@ -87,6 +88,7 @@ class ErrorCode extends $pb.ProtobufEnum { GridIdIsEmpty, BlockIdIsEmpty, RowIdIsEmpty, + OptionIdIsEmpty, FieldIdIsEmpty, FieldDoesNotExist, SelectOptionNameIsEmpty, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index b3efa2c0ad..625e2d9572 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -47,6 +47,7 @@ const ErrorCode$json = const { const {'1': 'GridIdIsEmpty', '2': 410}, const {'1': 'BlockIdIsEmpty', '2': 420}, const {'1': 'RowIdIsEmpty', '2': 430}, + const {'1': 'OptionIdIsEmpty', '2': 431}, const {'1': 'FieldIdIsEmpty', '2': 440}, const {'1': 'FieldDoesNotExist', '2': 441}, const {'1': 'SelectOptionNameIsEmpty', '2': 442}, @@ -56,4 +57,4 @@ const ErrorCode$json = const { }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFGaWVsZERvZXNOb3RFeGlzdBC5AxIcChdTZWxlY3RPcHRpb25OYW1lSXNFbXB0eRC6AxIaChVUeXBlT3B0aW9uRGF0YUlzRW1wdHkQwgMSEAoLSW52YWxpZERhdGEQ9AM='); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxIUCg9PcHRpb25JZElzRW1wdHkQrwMSEwoORmllbGRJZElzRW1wdHkQuAMSFgoRRmllbGREb2VzTm90RXhpc3QQuQMSHAoXU2VsZWN0T3B0aW9uTmFtZUlzRW1wdHkQugMSGgoVVHlwZU9wdGlvbkRhdGFJc0VtcHR5EMIDEhAKC0ludmFsaWREYXRhEPQD'); 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 7d69a59524..2de16d922c 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 @@ -20,9 +20,11 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext'); static const GridEvent CreateSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateSelectOption'); + static const GridEvent GetSelectOptions = GridEvent._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetSelectOptions'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent InsertSelectOption = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InsertSelectOption'); static const $core.List values = [ GetGridData, @@ -35,9 +37,11 @@ class GridEvent extends $pb.ProtobufEnum { DuplicateField, GetEditFieldContext, CreateSelectOption, + GetSelectOptions, CreateRow, GetRow, UpdateCell, + InsertSelectOption, ]; 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 dc5ca350b6..56b593c688 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 @@ -22,11 +22,13 @@ const GridEvent$json = const { const {'1': 'DuplicateField', '2': 15}, const {'1': 'GetEditFieldContext', '2': 16}, const {'1': 'CreateSelectOption', '2': 30}, + const {'1': 'GetSelectOptions', '2': 31}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, const {'1': 'UpdateCell', '2': 70}, + const {'1': 'InsertSelectOption', '2': 71}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg4KClVwZGF0ZUNlbGwQRg=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEhQKEEdldFNlbGVjdE9wdGlvbnMQHxINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxIOCgpVcGRhdGVDZWxsEEYSFgoSSW5zZXJ0U2VsZWN0T3B0aW9uEEc='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart index 2e1ac9610e..2b9fc8a5ce 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -198,3 +198,167 @@ class SelectOption extends $pb.GeneratedMessage { void clearColor() => clearField(3); } +enum SelectOptionChangesetPayload_OneOfInsertOptionId { + insertOptionId, + notSet +} + +enum SelectOptionChangesetPayload_OneOfDeleteOptionId { + deleteOptionId, + notSet +} + +class SelectOptionChangesetPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfInsertOptionId> _SelectOptionChangesetPayload_OneOfInsertOptionIdByTag = { + 3 : SelectOptionChangesetPayload_OneOfInsertOptionId.insertOptionId, + 0 : SelectOptionChangesetPayload_OneOfInsertOptionId.notSet + }; + static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfDeleteOptionId> _SelectOptionChangesetPayload_OneOfDeleteOptionIdByTag = { + 4 : SelectOptionChangesetPayload_OneOfDeleteOptionId.deleteOptionId, + 0 : SelectOptionChangesetPayload_OneOfDeleteOptionId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionChangesetPayload', createEmptyInstance: create) + ..oo(0, [3]) + ..oo(1, [4]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') + ..hasRequiredFields = false + ; + + SelectOptionChangesetPayload._() : super(); + factory SelectOptionChangesetPayload({ + $core.String? gridId, + $core.String? rowId, + $core.String? insertOptionId, + $core.String? deleteOptionId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (rowId != null) { + _result.rowId = rowId; + } + if (insertOptionId != null) { + _result.insertOptionId = insertOptionId; + } + if (deleteOptionId != null) { + _result.deleteOptionId = deleteOptionId; + } + return _result; + } + factory SelectOptionChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOptionChangesetPayload.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') + SelectOptionChangesetPayload clone() => SelectOptionChangesetPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOptionChangesetPayload copyWith(void Function(SelectOptionChangesetPayload) updates) => super.copyWith((message) => updates(message as SelectOptionChangesetPayload)) as SelectOptionChangesetPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOptionChangesetPayload create() => SelectOptionChangesetPayload._(); + SelectOptionChangesetPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOptionChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOptionChangesetPayload? _defaultInstance; + + SelectOptionChangesetPayload_OneOfInsertOptionId whichOneOfInsertOptionId() => _SelectOptionChangesetPayload_OneOfInsertOptionIdByTag[$_whichOneof(0)]!; + void clearOneOfInsertOptionId() => clearField($_whichOneof(0)); + + SelectOptionChangesetPayload_OneOfDeleteOptionId whichOneOfDeleteOptionId() => _SelectOptionChangesetPayload_OneOfDeleteOptionIdByTag[$_whichOneof(1)]!; + void clearOneOfDeleteOptionId() => clearField($_whichOneof(1)); + + @$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.String get insertOptionId => $_getSZ(2); + @$pb.TagNumber(3) + set insertOptionId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasInsertOptionId() => $_has(2); + @$pb.TagNumber(3) + void clearInsertOptionId() => clearField(3); + + @$pb.TagNumber(4) + $core.String get deleteOptionId => $_getSZ(3); + @$pb.TagNumber(4) + set deleteOptionId($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasDeleteOptionId() => $_has(3); + @$pb.TagNumber(4) + void clearDeleteOptionId() => clearField(4); +} + +class SelectOptionContext extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionContext', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'selectOptions', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..hasRequiredFields = false + ; + + SelectOptionContext._() : super(); + factory SelectOptionContext({ + $core.Iterable? options, + $core.Iterable? selectOptions, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (selectOptions != null) { + _result.selectOptions.addAll(selectOptions); + } + return _result; + } + factory SelectOptionContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOptionContext.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') + SelectOptionContext clone() => SelectOptionContext()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOptionContext copyWith(void Function(SelectOptionContext) updates) => super.copyWith((message) => updates(message as SelectOptionContext)) as SelectOptionContext; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOptionContext create() => SelectOptionContext._(); + SelectOptionContext createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOptionContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOptionContext? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.List get selectOptions => $_getList(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart index 7499864079..4002db9a33 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -60,3 +60,31 @@ const SelectOption$json = const { /// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSKAoFY29sb3IYAyABKA4yEi5TZWxlY3RPcHRpb25Db2xvclIFY29sb3I='); +@$core.Deprecated('Use selectOptionChangesetPayloadDescriptor instead') +const SelectOptionChangesetPayload$json = const { + '1': 'SelectOptionChangesetPayload', + '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': 'insert_option_id', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'insertOptionId'}, + const {'1': 'delete_option_id', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'deleteOptionId'}, + ], + '8': const [ + const {'1': 'one_of_insert_option_id'}, + const {'1': 'one_of_delete_option_id'}, + ], +}; + +/// Descriptor for `SelectOptionChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEioKEGluc2VydF9vcHRpb25faWQYAyABKAlIAFIOaW5zZXJ0T3B0aW9uSWQSKgoQZGVsZXRlX29wdGlvbl9pZBgEIAEoCUgBUg5kZWxldGVPcHRpb25JZEIZChdvbmVfb2ZfaW5zZXJ0X29wdGlvbl9pZEIZChdvbmVfb2ZfZGVsZXRlX29wdGlvbl9pZA=='); +@$core.Deprecated('Use selectOptionContextDescriptor instead') +const SelectOptionContext$json = const { + '1': 'SelectOptionContext', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'select_options', '3': 2, '4': 3, '5': 11, '6': '.SelectOption', '10': 'selectOptions'}, + ], +}; + +/// Descriptor for `SelectOptionContext`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionContextDescriptor = $convert.base64Decode('ChNTZWxlY3RPcHRpb25Db250ZXh0EicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSNAoOc2VsZWN0X29wdGlvbnMYAiADKAsyDS5TZWxlY3RPcHRpb25SDXNlbGVjdE9wdGlvbnM='); diff --git a/frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/down.sql new file mode 100644 index 0000000000..06daaca7de --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +DROP TABLE grid_block_index_table; +-- DROP TABLE grid_block_fts_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/up.sql new file mode 100644 index 0000000000..f55bc82f64 --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-04-05-015536_flowy-grid-block-index/up.sql @@ -0,0 +1,7 @@ +-- Your SQL goes here +CREATE TABLE grid_block_index_table ( + row_id TEXT NOT NULL PRIMARY KEY, + block_id TEXT NOT NULL +); + +-- CREATE VIRTUAL TABLE grid_block_fts_table USING FTS5(content, grid_id, block_id, row_id); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/src/schema.rs b/frontend/rust-lib/flowy-database/src/schema.rs index 6be116e806..8fddd037e0 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! { + grid_block_index_table (row_id) { + row_id -> Text, + block_id -> Text, + } +} + table! { grid_meta_rev_table (id) { id -> Integer, @@ -113,6 +120,7 @@ table! { allow_tables_to_appear_in_same_query!( app_table, doc_table, + grid_block_index_table, grid_meta_rev_table, grid_rev_table, kv_table, diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e90998b986..dd7675e803 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,5 +1,8 @@ use crate::manager::GridManager; -use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str, SelectOption}; +use crate::services::field::{ + default_type_option_builder_from_type, type_option_builder_from_json_str, SelectOption, + SelectOptionChangesetParams, SelectOptionChangesetPayload, +}; use crate::services::grid_editor::ClientGridEditor; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; @@ -40,7 +43,8 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let params: QueryFieldParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let field_metas = editor.get_field_metas(Some(params.field_orders)).await?; + let field_orders = params.field_orders.items; + let field_metas = editor.get_field_metas(Some(field_orders)).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); data_result(repeated_field) } @@ -203,3 +207,14 @@ pub(crate) async fn update_cell_handler( let _ = editor.update_cell(changeset).await?; Ok(()) } + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn insert_select_option_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let params: SelectOptionChangesetParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.insert_select_option(params).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 5183b8afb7..64c7c70e56 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -20,7 +20,8 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::CreateSelectOption, create_select_option_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) - .event(GridEvent::UpdateCell, update_cell_handler); + .event(GridEvent::UpdateCell, update_cell_handler) + .event(GridEvent::InsertSelectOption, insert_select_option_handler); module } @@ -58,6 +59,9 @@ pub enum GridEvent { #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] CreateSelectOption = 30, + #[event(input = "FieldIdentifierPayload", output = "SelectOptionContext")] + GetSelectOptions = 31, + #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 50, @@ -66,4 +70,7 @@ pub enum GridEvent { #[event(input = "CellMetaChangeset")] UpdateCell = 70, + + #[event(input = "InsertSelectOptionPayload")] + InsertSelectOption = 71, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index e4f24a8547..686f539b74 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,5 +1,7 @@ use crate::services::grid_editor::ClientGridEditor; -use crate::services::kv_persistence::GridKVPersistence; +use crate::services::persistence::block_index::BlockIndexPersistence; +use crate::services::persistence::kv::GridKVPersistence; +use crate::services::persistence::GridDatabase; use bytes::Bytes; use dashmap::DashMap; use flowy_database::ConnectionPool; @@ -21,20 +23,24 @@ pub trait GridUser: Send + Sync { pub struct GridManager { editor_map: Arc, grid_user: Arc, - kv_persistence: Arc>>>, + block_index_persistence: 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, + database: Arc, + ) -> Self { 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)); + let kv_persistence = Arc::new(GridKVPersistence::new(database.clone())); + let block_index_persistence = Arc::new(BlockIndexPersistence::new(database)); Self { editor_map: grid_editors, grid_user, kv_persistence, + block_index_persistence, } } @@ -111,7 +117,8 @@ impl GridManager { ) -> Result, FlowyError> { let user = self.grid_user.clone(); let rev_manager = self.make_grid_rev_manager(grid_id, pool.clone())?; - let grid_editor = ClientGridEditor::new(grid_id, user, rev_manager).await?; + let grid_editor = + ClientGridEditor::new(grid_id, user, rev_manager, self.block_index_persistence.clone()).await?; Ok(grid_editor) } @@ -135,20 +142,6 @@ impl GridManager { let rev_manager = RevisionManager::new(&user_id, block_d, rev_persistence); Ok(rev_manager) } - - #[allow(dead_code)] - async fn get_kv_persistence(&self) -> FlowyResult> { - let read_guard = self.kv_persistence.read().await; - 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().await = Some(kv_persistence.clone()); - Ok(kv_persistence) - } } pub struct GridEditorMap { 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 368c4df718..ae1dfe161d 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 @@ -35,9 +35,11 @@ pub enum GridEvent { DuplicateField = 15, GetEditFieldContext = 16, CreateSelectOption = 30, + GetSelectOptions = 31, CreateRow = 50, GetRow = 51, UpdateCell = 70, + InsertSelectOption = 71, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -57,9 +59,11 @@ impl ::protobuf::ProtobufEnum for GridEvent { 15 => ::std::option::Option::Some(GridEvent::DuplicateField), 16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext), 30 => ::std::option::Option::Some(GridEvent::CreateSelectOption), + 31 => ::std::option::Option::Some(GridEvent::GetSelectOptions), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), 70 => ::std::option::Option::Some(GridEvent::UpdateCell), + 71 => ::std::option::Option::Some(GridEvent::InsertSelectOption), _ => ::std::option::Option::None } } @@ -76,9 +80,11 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::DuplicateField, GridEvent::GetEditFieldContext, GridEvent::CreateSelectOption, + GridEvent::GetSelectOptions, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, + GridEvent::InsertSelectOption, ]; values } @@ -107,13 +113,14 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xf4\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xa2\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x16\n\x12Creat\ - eSelectOption\x10\x1e\x12\r\n\tCreateRow\x102\x12\n\n\x06GetRow\x103\x12\ - \x0e\n\nUpdateCell\x10Fb\x06proto3\ + eSelectOption\x10\x1e\x12\x14\n\x10GetSelectOptions\x10\x1f\x12\r\n\tCre\ + ateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\x16\n\ + \x12InsertSelectOption\x10Gb\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/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index ae57224d2e..ba0e1bebe9 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -657,6 +657,585 @@ impl ::protobuf::reflect::ProtobufValue for SelectOption { } } +#[derive(PartialEq,Clone,Default)] +pub struct SelectOptionChangesetPayload { + // message fields + pub grid_id: ::std::string::String, + pub row_id: ::std::string::String, + // message oneof groups + pub one_of_insert_option_id: ::std::option::Option, + pub one_of_delete_option_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOptionChangesetPayload { + fn default() -> &'a SelectOptionChangesetPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionChangesetPayload_oneof_one_of_insert_option_id { + insert_option_id(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionChangesetPayload_oneof_one_of_delete_option_id { + delete_option_id(::std::string::String), +} + +impl SelectOptionChangesetPayload { + pub fn new() -> SelectOptionChangesetPayload { + ::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()) + } + + // string insert_option_id = 3; + + + pub fn get_insert_option_id(&self) -> &str { + match self.one_of_insert_option_id { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v)) => v, + _ => "", + } + } + pub fn clear_insert_option_id(&mut self) { + self.one_of_insert_option_id = ::std::option::Option::None; + } + + pub fn has_insert_option_id(&self) -> bool { + match self.one_of_insert_option_id { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_insert_option_id(&mut self, v: ::std::string::String) { + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_insert_option_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(_)) = self.one_of_insert_option_id { + } else { + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(::std::string::String::new())); + } + match self.one_of_insert_option_id { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_insert_option_id(&mut self) -> ::std::string::String { + if self.has_insert_option_id() { + match self.one_of_insert_option_id.take() { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // string delete_option_id = 4; + + + pub fn get_delete_option_id(&self) -> &str { + match self.one_of_delete_option_id { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v)) => v, + _ => "", + } + } + pub fn clear_delete_option_id(&mut self) { + self.one_of_delete_option_id = ::std::option::Option::None; + } + + pub fn has_delete_option_id(&self) -> bool { + match self.one_of_delete_option_id { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_delete_option_id(&mut self, v: ::std::string::String) { + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_delete_option_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(_)) = self.one_of_delete_option_id { + } else { + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(::std::string::String::new())); + } + match self.one_of_delete_option_id { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_delete_option_id(&mut self) -> ::std::string::String { + if self.has_delete_option_id() { + match self.one_of_delete_option_id.take() { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for SelectOptionChangesetPayload { + 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::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.row_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { + match v { + &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { + my_size += ::protobuf::rt::string_size(3, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { + match v { + &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { + my_size += ::protobuf::rt::string_size(4, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.row_id.is_empty() { + os.write_string(2, &self.row_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { + match v { + &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { + os.write_string(3, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { + match v { + &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { + os.write_string(4, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SelectOptionChangesetPayload { + SelectOptionChangesetPayload::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: &SelectOptionChangesetPayload| { &m.grid_id }, + |m: &mut SelectOptionChangesetPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &SelectOptionChangesetPayload| { &m.row_id }, + |m: &mut SelectOptionChangesetPayload| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "insert_option_id", + SelectOptionChangesetPayload::has_insert_option_id, + SelectOptionChangesetPayload::get_insert_option_id, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "delete_option_id", + SelectOptionChangesetPayload::has_delete_option_id, + SelectOptionChangesetPayload::get_delete_option_id, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionChangesetPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOptionChangesetPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionChangesetPayload::new) + } +} + +impl ::protobuf::Clear for SelectOptionChangesetPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.row_id.clear(); + self.one_of_insert_option_id = ::std::option::Option::None; + self.one_of_delete_option_id = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOptionChangesetPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionChangesetPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SelectOptionContext { + // message fields + pub options: ::protobuf::RepeatedField, + pub select_options: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOptionContext { + fn default() -> &'a SelectOptionContext { + ::default_instance() + } +} + +impl SelectOptionContext { + pub fn new() -> SelectOptionContext { + ::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()) + } + + // repeated .SelectOption select_options = 2; + + + pub fn get_select_options(&self) -> &[SelectOption] { + &self.select_options + } + pub fn clear_select_options(&mut self) { + self.select_options.clear(); + } + + // Param is passed by value, moved + pub fn set_select_options(&mut self, v: ::protobuf::RepeatedField) { + self.select_options = v; + } + + // Mutable pointer to the field. + pub fn mut_select_options(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.select_options + } + + // Take field + pub fn take_select_options(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.select_options, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for SelectOptionContext { + fn is_initialized(&self) -> bool { + for v in &self.options { + if !v.is_initialized() { + return false; + } + }; + for v in &self.select_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 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.select_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; + for value in &self.options { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.select_options { + 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.options { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.select_options { + 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() -> SelectOptionContext { + SelectOptionContext::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: &SelectOptionContext| { &m.options }, + |m: &mut SelectOptionContext| { &mut m.options }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "select_options", + |m: &SelectOptionContext| { &m.select_options }, + |m: &mut SelectOptionContext| { &mut m.select_options }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionContext", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOptionContext { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionContext::new) + } +} + +impl ::protobuf::Clear for SelectOptionContext { + fn clear(&mut self) { + self.options.clear(); + self.select_options.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOptionContext { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionContext { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum SelectOptionColor { Purple = 0, @@ -736,11 +1315,18 @@ static file_descriptor_proto_data: &'static [u8] = b"\ s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"\\\n\x0cS\ electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ \x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\x18\x03\x20\x01(\x0e2\x12.S\ - electOptionColorR\x05color*y\n\x11SelectOptionColor\x12\n\n\x06Purple\ - \x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightPink\x10\x02\x12\n\n\x06O\ - range\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\n\x04Lime\x10\x05\x12\t\ - \n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\x12\x08\n\x04Blue\x10\x08b\ - \x06proto3\ + electOptionColorR\x05color\"\xdc\x01\n\x1cSelectOptionChangesetPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ + \x18\x02\x20\x01(\tR\x05rowId\x12*\n\x10insert_option_id\x18\x03\x20\x01\ + (\tH\0R\x0einsertOptionId\x12*\n\x10delete_option_id\x18\x04\x20\x01(\tH\ + \x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_\ + of_delete_option_id\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\ + \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\n\x0eselect_options\ + \x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOptions*y\n\x11SelectOptio\ + nColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightP\ + ink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\ + \n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\ + \x12\x08\n\x04Blue\x10\x08b\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 9d2ea5961f..4703711cb3 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 @@ -11,7 +11,9 @@ enum GridEvent { DuplicateField = 15; GetEditFieldContext = 16; CreateSelectOption = 30; + GetSelectOptions = 31; CreateRow = 50; GetRow = 51; UpdateCell = 70; + InsertSelectOption = 71; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index f07e2273bb..37dc0a36c1 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -13,6 +13,16 @@ message SelectOption { string name = 2; SelectOptionColor color = 3; } +message SelectOptionChangesetPayload { + string grid_id = 1; + string row_id = 2; + oneof one_of_insert_option_id { string insert_option_id = 3; }; + oneof one_of_delete_option_id { string delete_option_id = 4; }; +} +message SelectOptionContext { + repeated SelectOption options = 1; + repeated SelectOption select_options = 2; +} enum SelectOptionColor { Purple = 0; Pink = 1; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 353185f498..c5082a1c2e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,6 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; -use crate::services::row::{make_cell, make_row_ids_per_block, GridBlockSnapshot}; +use crate::services::persistence::block_index::BlockIndexPersistence; +use crate::services::row::{make_block_row_ids, make_cell_by_field_id, GridBlockSnapshot}; use bytes::Bytes; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; @@ -28,20 +29,24 @@ pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, editor_map: DashMap>, - block_id_by_row_id: DashMap, + persistence: Arc, } impl GridBlockMetaEditorManager { - pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { + pub(crate) async fn new( + grid_id: &str, + user: &Arc, + blocks: Vec, + persistence: Arc, + ) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); - let block_id_by_row_id = DashMap::new(); let grid_id = grid_id.to_owned(); let manager = Self { grid_id, user, editor_map, - block_id_by_row_id, + persistence, }; Ok(manager) } @@ -60,14 +65,18 @@ impl GridBlockMetaEditorManager { } } + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + let block_id = self.persistence.get_block_id(row_id)?; + Ok(self.get_editor(&block_id).await?) + } + pub(crate) async fn create_row( &self, block_id: &str, row_meta: RowMeta, start_row_id: Option, ) -> FlowyResult { - self.block_id_by_row_id - .insert(row_meta.id.clone(), row_meta.block_id.clone()); + let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?; let editor = self.get_editor(&row_meta.block_id).await?; let row_count = editor.create_row(row_meta, start_row_id).await?; self.notify_block_did_update_row(block_id).await?; @@ -83,7 +92,7 @@ impl GridBlockMetaEditorManager { let editor = self.get_editor(&block_id).await?; let mut row_count = 0; for row in &row_metas { - self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); + let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; row_count = editor.create_row(row.clone(), None).await?; } changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); @@ -95,12 +104,11 @@ impl GridBlockMetaEditorManager { pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { let mut changesets = vec![]; - let row_ids_per_blocks = make_row_ids_per_block(&row_orders); - for row_ids_per_block in row_ids_per_blocks { - let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let row_count = editor.delete_rows(row_ids_per_block.row_ids).await?; + for block_row_ids in make_block_row_ids(&row_orders) { + let editor = self.get_editor(&block_row_ids.block_id).await?; + let row_count = editor.delete_rows(block_row_ids.row_ids).await?; - let changeset = GridBlockMetaChangeset::from_row_count(&row_ids_per_block.block_id, row_count); + let changeset = GridBlockMetaChangeset::from_row_count(&block_row_ids.block_id, row_count); changesets.push(changeset); } @@ -114,10 +122,17 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult>> { - let editor = self.get_editor(block_id).await?; + pub async fn update_row_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { + let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let _ = editor.update_row(changeset.clone()).await?; + self.notify_did_update_cells(changeset, field_metas)?; + Ok(()) + } + + pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult>> { + let editor = self.get_editor_from_row_id(row_id).await?; let row_ids = vec![row_id.to_owned()]; - let mut row_metas = editor.get_row_metas(&Some(row_ids)).await?; + let mut row_metas = editor.get_row_metas(Some(row_ids)).await?; if row_metas.is_empty() { Ok(None) } else { @@ -125,23 +140,11 @@ impl GridBlockMetaEditorManager { } } - pub async fn update_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { - let editor = self.get_editor_from_row_id(&changeset.row_id).await?; - let _ = editor.update_row(changeset.clone()).await?; - self.notify_did_update_cells(changeset, field_metas)?; - Ok(()) - } - pub(crate) async fn make_block_snapshots(&self, block_ids: Vec) -> FlowyResult> { let mut snapshots = vec![]; for block_id in block_ids { let editor = self.get_editor(&block_id).await?; - let row_metas = editor.get_row_metas(&None).await?; - row_metas.iter().for_each(|row_meta| { - self.block_id_by_row_id - .insert(row_meta.id.clone(), row_meta.block_id.clone()); - }); - + let row_metas = editor.get_row_metas(None).await?; snapshots.push(GridBlockSnapshot { block_id, row_metas }); } Ok(snapshots) @@ -164,19 +167,6 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { - match self.block_id_by_row_id.get(row_id) { - None => { - let msg = format!( - "Update Row failed. Can't find the corresponding block with row_id: {}", - row_id - ); - Err(FlowyError::internal().context(msg)) - } - Some(block_id) => Ok(self.get_editor(&block_id).await?), - } - } - async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { let block_order: GridBlockOrder = block_id.into(); send_dart_notification(&self.grid_id, GridNotification::DidUpdateRow) @@ -196,7 +186,7 @@ impl GridBlockMetaEditorManager { .cell_by_field_id .into_iter() .for_each( - |(field_id, cell_meta)| match make_cell(&field_meta_map, field_id, cell_meta) { + |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) { None => {} Some((_, cell)) => cells.push(cell), }, @@ -290,23 +280,13 @@ impl ClientGridBlockMetaEditor { Ok(row_count) } - pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult { - let row_id = changeset.row_id.clone(); + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let _ = self.modify(|pad| Ok(pad.update_row(changeset)?)).await?; - let row_ids = vec![row_id.clone()]; - let mut row_metas = self.get_row_metas(&Some(row_ids)).await?; - debug_assert_eq!(row_metas.len(), 1); - - if row_metas.is_empty() { - return Err(FlowyError::record_not_found().context(format!("Can't find the row with id: {}", &row_id))); - } else { - let a = (**row_metas.pop().as_ref().unwrap()).clone(); - Ok(a) - } + Ok(()) } - pub async fn get_row_metas(&self, row_ids: &Option>) -> FlowyResult>> { - let row_metas = self.pad.read().await.get_row_metas(row_ids)?; + pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { + let row_metas = self.pad.read().await.get_row_metas(&row_ids)?; Ok(row_metas) } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 84d693edd0..b91409c904 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,6 +1,6 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataSerde, TypeOptionCellData}; +use crate::services::row::{CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; @@ -40,7 +40,7 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox); const YES: &str = "Yes"; const NO: &str = "No"; -impl CellDataSerde for CheckboxTypeOption { +impl CellDataOperation for CheckboxTypeOption { fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_text() || !type_option_cell_data.is_checkbox() { @@ -81,7 +81,7 @@ fn string_to_bool(bool_str: &str) -> bool { mod tests { use crate::services::field::CheckboxTypeOption; use crate::services::field::FieldBuilder; - use crate::services::row::CellDataSerde; + use crate::services::row::CellDataOperation; use flowy_grid_data_model::entities::FieldType; #[test] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 5dd88a4a67..2c67c69fe5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,5 +1,5 @@ use crate::impl_type_option; -use crate::services::row::{CellDataSerde, TypeOptionCellData}; +use crate::services::row::{CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; @@ -42,7 +42,7 @@ impl DateTypeOption { } } -impl CellDataSerde for DateTypeOption { +impl CellDataOperation for DateTypeOption { fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_date() { @@ -185,7 +185,7 @@ impl std::default::Default for TimeFormat { mod tests { use crate::services::field::FieldBuilder; use crate::services::field::{DateFormat, DateTypeOption, TimeFormat}; - use crate::services::row::{CellDataSerde, TypeOptionCellData}; + use crate::services::row::{CellDataOperation, TypeOptionCellData}; use flowy_grid_data_model::entities::FieldType; use strum::IntoEnumIterator; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 7cee8a3b39..55ce729a7f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -1,5 +1,5 @@ use crate::impl_type_option; -use crate::services::row::{CellDataSerde, TypeOptionCellData}; +use crate::services::row::{CellDataOperation, TypeOptionCellData}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; @@ -76,7 +76,7 @@ pub struct NumberTypeOption { } impl_type_option!(NumberTypeOption, FieldType::Number); -impl CellDataSerde for NumberTypeOption { +impl CellDataOperation for NumberTypeOption { fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() { @@ -205,7 +205,7 @@ fn make_strip_symbol() -> Vec { mod tests { use crate::services::field::FieldBuilder; use crate::services::field::{NumberFormat, NumberTypeOption}; - use crate::services::row::{CellDataSerde, TypeOptionCellData}; + use crate::services::row::{CellDataOperation, TypeOptionCellData}; use flowy_grid_data_model::entities::FieldType; use strum::IntoEnumIterator; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 5768a92f70..1774b12ce3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,11 +1,12 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataSerde, TypeOptionCellData}; +use crate::services::row::{CellDataOperation, TypeOptionCellData}; use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::{FlowyError, FlowyResult}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -24,7 +25,7 @@ pub struct SingleSelectTypeOption { } impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); -impl CellDataSerde for SingleSelectTypeOption { +impl CellDataOperation for SingleSelectTypeOption { fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { @@ -80,7 +81,7 @@ pub struct MultiSelectTypeOption { } impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); -impl CellDataSerde for MultiSelectTypeOption { +impl CellDataOperation for MultiSelectTypeOption { fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { @@ -190,6 +191,77 @@ impl SelectOption { } } +#[derive(Clone, Debug, Default, ProtoBuf)] +pub struct SelectOptionChangesetPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] + pub field_id: String, + + #[pb(index = 4, one_of)] + pub insert_option_id: Option, + + #[pb(index = 5, one_of)] + pub delete_option_id: Option, +} + +#[derive(Clone)] +pub struct SelectOptionChangesetParams { + pub grid_id: String, + pub field_id: String, + pub row_id: String, + pub insert_option_id: Option, + pub delete_option_id: Option, +} + +impl TryInto for SelectOptionChangesetPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let insert_option_id = match self.insert_option_id { + None => None, + Some(insert_option_id) => Some( + NotEmptyStr::parse(insert_option_id) + .map_err(|_| ErrorCode::OptionIdIsEmpty)? + .0, + ), + }; + + let delete_option_id = match self.delete_option_id { + None => None, + Some(delete_option_id) => Some( + NotEmptyStr::parse(delete_option_id) + .map_err(|_| ErrorCode::OptionIdIsEmpty)? + .0, + ), + }; + + Ok(SelectOptionChangesetParams { + grid_id: grid_id.0, + row_id: row_id.0, + field_id: field_id.0, + insert_option_id, + delete_option_id, + }) + } +} + +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct SelectOptionContext { + #[pb(index = 1)] + pub options: Vec, + + #[pb(index = 2)] + pub select_options: Vec, +} + #[derive(ProtoBuf_Enum, Serialize, Deserialize, Debug, Clone)] #[repr(u8)] pub enum SelectOptionColor { @@ -213,7 +285,7 @@ impl std::default::Default for SelectOptionColor { #[cfg(test)] mod tests { use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption}; - use crate::services::row::CellDataSerde; + use crate::services::row::CellDataOperation; #[test] #[should_panic] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 87434a3cdb..4b7195a305 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,6 +1,6 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{deserialize_cell_data, CellDataSerde, TypeOptionCellData}; +use crate::services::row::{deserialize_cell_data, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; @@ -30,7 +30,7 @@ pub struct RichTextTypeOption { } impl_type_option!(RichTextTypeOption, FieldType::RichText); -impl CellDataSerde for RichTextTypeOption { +impl CellDataOperation for RichTextTypeOption { fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() @@ -61,7 +61,7 @@ impl CellDataSerde for RichTextTypeOption { mod tests { use crate::services::field::FieldBuilder; use crate::services::field::*; - use crate::services::row::{CellDataSerde, TypeOptionCellData}; + use crate::services::row::{CellDataOperation, TypeOptionCellData}; use flowy_grid_data_model::entities::FieldType; #[test] 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 59840d1e4f..708e07fd74 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,10 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; +use crate::services::field::{ + default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder, SelectOptionChangesetParams, +}; +use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; @@ -30,17 +33,16 @@ impl ClientGridEditor { grid_id: &str, user: Arc, mut rev_manager: RevisionManager, + persistence: Arc, ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); let pad = Arc::new(RwLock::new(grid_pad)); + let blocks = pad.read().await.get_block_metas().clone(); - let block_meta_manager = Arc::new( - GridBlockMetaEditorManager::new(grid_id, &user, pad.read().await.get_block_metas().clone()).await?, - ); - + let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, blocks, persistence).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, @@ -223,12 +225,12 @@ impl ClientGridEditor { } } - pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult> { - match self.block_meta_manager.get_row(block_id, row_id).await? { + pub async fn get_row(&self, row_id: &str) -> FlowyResult> { + match self.block_meta_manager.get_row_meta(row_id).await? { None => Ok(None), - Some(row) => { + Some(row_meta) => { let field_metas = self.get_field_metas(None).await?; - let row_metas = vec![row]; + let row_metas = vec![row_meta]; let mut rows = make_rows_from_row_metas(&field_metas, &row_metas); debug_assert!(rows.len() == 1); Ok(rows.pop()) @@ -236,12 +238,28 @@ impl ClientGridEditor { } } + pub async fn get_cell_meta(&self, row_id: &str, field_id: &str) -> FlowyResult> { + let row_meta = self.block_meta_manager.get_row_meta(row_id).await?; + match row_meta { + None => Ok(None), + Some(row_meta) => { + let cell_meta = row_meta.cell_by_field_id.get(field_id).cloned(); + Ok(cell_meta) + } + } + } + + pub async fn apply_select_option(&self, params: SelectOptionChangesetParams) -> FlowyResult<()> { + let cell_meta = self.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; + todo!() + } + pub async fn update_cell(&self, mut changeset: CellMetaChangeset) -> FlowyResult<()> { if let Some(cell_data) = changeset.data.as_ref() { match self.pad.read().await.get_field(&changeset.field_id) { None => { - return Err(FlowyError::internal() - .context(format!("Can not find the field with id: {}", &changeset.field_id))); + let msg = format!("Can not find the field with id: {}", &changeset.field_id); + return Err(FlowyError::internal().context(msg)); } Some(field_meta) => { let cell_data = serialize_cell_data(cell_data, field_meta)?; @@ -254,7 +272,7 @@ impl ClientGridEditor { let row_changeset: RowMetaChangeset = changeset.into(); let _ = self .block_meta_manager - .update_cells(&field_metas, row_changeset) + .update_row_cells(&field_metas, row_changeset) .await?; Ok(()) } @@ -296,7 +314,7 @@ impl ClientGridEditor { }) } - pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { + pub async fn get_field_metas(&self, field_orders: Option>) -> FlowyResult> { let expected_len = match field_orders.as_ref() { None => 0, Some(field_orders) => field_orders.len(), @@ -310,7 +328,6 @@ impl ClientGridEditor { ); debug_assert!(field_metas.len() == expected_len); } - // field_metas.retain(|field_meta| field_meta.visibility); Ok(field_metas) } @@ -385,8 +402,8 @@ impl ClientGridEditor { } async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { - let field_orders: RepeatedFieldOrder = vec![FieldOrder::from(field_id)].into(); - let mut field_metas = self.get_field_metas(Some(field_orders)).await?; + let field_order = FieldOrder::from(field_id); + let mut field_metas = self.get_field_metas(Some(field_order.into())).await?; debug_assert!(field_metas.len() == 1); if let Some(field_meta) = field_metas.pop() { diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index d3eb2d2857..6ae3be1dca 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -3,5 +3,5 @@ mod util; pub mod block_meta_editor; pub mod field; pub mod grid_editor; -pub mod kv_persistence; +pub mod persistence; pub mod row; diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs new file mode 100644 index 0000000000..a639776394 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs @@ -0,0 +1,49 @@ +use crate::services::persistence::GridDatabase; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; +use flowy_database::{ + prelude::*, + schema::{grid_block_index_table, grid_block_index_table::dsl}, + ConnectionPool, +}; +use flowy_error::FlowyResult; +use std::sync::Arc; + +pub struct BlockIndexPersistence { + database: Arc, +} + +impl BlockIndexPersistence { + pub fn new(database: Arc) -> Self { + Self { database } + } + + pub fn get_block_id(&self, row_id: &str) -> FlowyResult { + let conn = self.database.db_connection()?; + let block_id = dsl::grid_block_index_table + .filter(grid_block_index_table::row_id.eq(row_id)) + .select(grid_block_index_table::block_id) + .first::(&*conn)?; + + Ok(block_id) + } + + pub fn insert_or_update(&self, block_id: &str, row_id: &str) -> FlowyResult<()> { + let conn = self.database.db_connection()?; + let item = IndexItem { + row_id: row_id.to_string(), + block_id: block_id.to_string(), + }; + let _ = diesel::replace_into(grid_block_index_table::table) + .values(item) + .execute(&*conn)?; + Ok(()) + } +} + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] +#[table_name = "grid_block_index_table"] +#[primary_key(row_id)] +struct IndexItem { + row_id: String, + block_id: String, +} diff --git a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs similarity index 95% rename from frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs rename to frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs index 89961ace48..cf66211fab 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs @@ -1,3 +1,4 @@ +use crate::services::persistence::GridDatabase; use ::diesel::{query_dsl::*, ExpressionMethods}; use bytes::Bytes; use diesel::SqliteConnection; @@ -29,19 +30,19 @@ pub trait KVTransaction { } pub struct GridKVPersistence { - pool: Arc, + database: Arc, } impl GridKVPersistence { - pub fn new(pool: Arc) -> Self { - Self { pool } + pub fn new(database: Arc) -> Self { + Self { database } } pub fn begin_transaction(&self, f: F) -> FlowyResult where F: for<'a> FnOnce(SqliteTransaction<'a>) -> FlowyResult, { - let conn = self.pool.get()?; + let conn = self.database.db_connection()?; conn.immediate_transaction::<_, FlowyError, _>(|| { let sql_transaction = SqliteTransaction { conn: &conn }; f(sql_transaction) diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/mod.rs new file mode 100644 index 0000000000..d6167cf8e6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/mod.rs @@ -0,0 +1,16 @@ +use flowy_database::{ConnectionPool, DBConnection}; +use flowy_error::FlowyError; +use std::sync::Arc; + +pub mod block_index; +pub mod kv; + +pub trait GridDatabase: Send + Sync { + fn db_pool(&self) -> Result, FlowyError>; + + fn db_connection(&self) -> Result { + let pool = self.db_pool()?; + let conn = pool.get().map_err(|e| FlowyError::internal().context(e))?; + Ok(conn) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs similarity index 97% rename from frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs rename to frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index 259e052ab7..ad0dcb1646 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -1,11 +1,13 @@ use crate::services::field::*; +use bytes::Bytes; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; -pub trait CellDataSerde { +pub trait CellDataOperation { fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; fn serialize_cell_data(&self, data: &str) -> Result; + // fn apply_changeset() } #[derive(Serialize, Deserialize)] @@ -60,7 +62,6 @@ impl TypeOptionCellData { } } -#[allow(dead_code)] pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result { match field_meta.field_type { FieldType::RichText => RichTextTypeOption::from(field_meta).serialize_cell_data(data), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index fec4ea8d8c..e2727cdf34 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -1,7 +1,7 @@ -mod cell_data_serde; +mod cell_data_operation; mod row_builder; mod row_loader; -pub use cell_data_serde::*; +pub use cell_data_operation::*; pub use row_builder::*; pub(crate) use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index cbaae78fed..698d4ac4ec 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,4 +1,5 @@ use crate::services::row::serialize_cell_data; +use bytes::Bytes; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 55ee0ec8c8..c497d7e12d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -8,14 +8,14 @@ use std::collections::HashMap; use std::sync::Arc; -pub(crate) struct RowIdsPerBlock { +pub(crate) struct BlockRowIds { pub(crate) block_id: String, pub(crate) row_ids: Vec, } -impl RowIdsPerBlock { +impl BlockRowIds { pub fn new(block_id: &str) -> Self { - RowIdsPerBlock { + BlockRowIds { block_id: block_id.to_owned(), row_ids: vec![], } @@ -27,13 +27,13 @@ pub struct GridBlockSnapshot { pub row_metas: Vec>, } -pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { - let mut map: HashMap<&String, RowIdsPerBlock> = HashMap::new(); +pub(crate) fn make_block_row_ids(row_orders: &[RowOrder]) -> Vec { + let mut map: HashMap<&String, BlockRowIds> = HashMap::new(); row_orders.iter().for_each(|row_order| { let block_id = &row_order.block_id; let row_id = row_order.row_id.clone(); map.entry(block_id) - .or_insert_with(|| RowIdsPerBlock::new(block_id)) + .or_insert_with(|| BlockRowIds::new(block_id)) .row_ids .push(row_id); }); @@ -41,13 +41,13 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec, field_id: String, - raw_cell: CellMeta, + cell_meta: CellMeta, ) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; - match deserialize_cell_data(raw_cell.data, field_meta) { + match deserialize_cell_data(cell_meta.data, field_meta) { Ok(content) => { let cell = Cell::new(&field_id, content); Some((field_id, cell)) @@ -59,6 +59,18 @@ pub fn make_cell( } } +#[allow(dead_code)] +pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { + let cell_meta = row_meta.cell_by_field_id.get(field_id)?.clone(); + match deserialize_cell_data(cell_meta.data, field_meta) { + Ok(content) => Some(Cell::new(&field_id, content)), + Err(e) => { + tracing::error!("{}", e); + None + } + } +} + pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec { row_metas.iter().map(RowOrder::from).collect::>() } @@ -74,7 +86,7 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc>(); Row { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 138ccf4bba..26dd3896dc 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,7 +4,7 @@ use chrono::NaiveDateTime; use flowy_grid::services::field::{ MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, }; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowMetaBuilder}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataOperation, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, TypeOptionDataEntry, 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 514c320511..88073a3107 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 @@ -2,6 +2,7 @@ use crate::FlowyError; use bytes::Bytes; use flowy_database::ConnectionPool; use flowy_grid::manager::{GridManager, GridUser}; +use flowy_grid::services::persistence::GridDatabase; use flowy_net::ws::connection::FlowyWebSocketConnect; use flowy_revision::{RevisionWebSocket, WSStateReceiver}; use flowy_sync::entities::ws_data::ClientRevisionWSData; @@ -16,9 +17,20 @@ pub struct GridDepsResolver(); impl GridDepsResolver { pub fn resolve(ws_conn: Arc, user_session: Arc) -> Arc { - let user = Arc::new(GridUserImpl(user_session)); + let user = Arc::new(GridUserImpl(user_session.clone())); let rev_web_socket = Arc::new(GridWebSocket(ws_conn)); - Arc::new(GridManager::new(user, rev_web_socket)) + Arc::new(GridManager::new( + user, + rev_web_socket, + Arc::new(GridDatabaseImpl(user_session)), + )) + } +} + +struct GridDatabaseImpl(Arc); +impl GridDatabase for GridDatabaseImpl { + fn db_pool(&self) -> Result, FlowyError> { + self.0.db_pool().map_err(|e| FlowyError::internal().context(e)) } } diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index 3b0cf331ee..30af0f9885 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -95,6 +95,8 @@ pub enum ErrorCode { BlockIdIsEmpty = 420, #[display(fmt = "Row id is empty")] RowIdIsEmpty = 430, + #[display(fmt = "Select option id is empty")] + OptionIdIsEmpty = 431, #[display(fmt = "Field id is empty")] FieldIdIsEmpty = 440, #[display(fmt = "Field doesn't exist")] diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index 6e6db9139b..f3d669a681 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -60,6 +60,7 @@ pub enum ErrorCode { GridIdIsEmpty = 410, BlockIdIsEmpty = 420, RowIdIsEmpty = 430, + OptionIdIsEmpty = 431, FieldIdIsEmpty = 440, FieldDoesNotExist = 441, SelectOptionNameIsEmpty = 442, @@ -109,6 +110,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 410 => ::std::option::Option::Some(ErrorCode::GridIdIsEmpty), 420 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty), 430 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), + 431 => ::std::option::Option::Some(ErrorCode::OptionIdIsEmpty), 440 => ::std::option::Option::Some(ErrorCode::FieldIdIsEmpty), 441 => ::std::option::Option::Some(ErrorCode::FieldDoesNotExist), 442 => ::std::option::Option::Some(ErrorCode::SelectOptionNameIsEmpty), @@ -155,6 +157,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::GridIdIsEmpty, ErrorCode::BlockIdIsEmpty, ErrorCode::RowIdIsEmpty, + ErrorCode::OptionIdIsEmpty, ErrorCode::FieldIdIsEmpty, ErrorCode::FieldDoesNotExist, ErrorCode::SelectOptionNameIsEmpty, @@ -188,7 +191,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\x9e\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xb4\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\ \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\ @@ -207,10 +210,11 @@ static file_descriptor_proto_data: &'static [u8] = b"\ IsEmpty\x10\xb6\x02\x12\x12\n\rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUs\ erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x12\n\rG\ ridIdIsEmpty\x10\x9a\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\xa4\x03\x12\x11\ - \n\x0cRowIdIsEmpty\x10\xae\x03\x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\ - \x12\x16\n\x11FieldDoesNotExist\x10\xb9\x03\x12\x1c\n\x17SelectOptionNam\ - eIsEmpty\x10\xba\x03\x12\x1a\n\x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\ - \x10\n\x0bInvalidData\x10\xf4\x03b\x06proto3\ + \n\x0cRowIdIsEmpty\x10\xae\x03\x12\x14\n\x0fOptionIdIsEmpty\x10\xaf\x03\ + \x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\x12\x16\n\x11FieldDoesNotExist\ + \x10\xb9\x03\x12\x1c\n\x17SelectOptionNameIsEmpty\x10\xba\x03\x12\x1a\n\ + \x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\x10\n\x0bInvalidData\x10\xf4\ + \x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index d435d558dc..8ea2941815 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -36,6 +36,7 @@ enum ErrorCode { GridIdIsEmpty = 410; BlockIdIsEmpty = 420; RowIdIsEmpty = 430; + OptionIdIsEmpty = 431; FieldIdIsEmpty = 440; FieldDoesNotExist = 441; SelectOptionNameIsEmpty = 442; 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 1dd2220f13..c92a3b23a4 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -92,6 +92,12 @@ pub struct FieldOrder { pub field_id: String, } +impl std::convert::Into> for FieldOrder { + fn into(self) -> Vec { + vec![self] + } +} + impl std::convert::From<&FieldMeta> for FieldOrder { fn from(field_meta: &FieldMeta) -> Self { Self { diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 9be0faa99d..de8ac320f3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -393,14 +393,12 @@ pub struct CellMetaChangeset { impl std::convert::From for RowMetaChangeset { fn from(changeset: CellMetaChangeset) -> Self { let mut cell_by_field_id = HashMap::with_capacity(1); - if let Some(data) = changeset.data { - let field_id = changeset.field_id; - let cell_meta = CellMeta { - field_id: field_id.clone(), - data, - }; - cell_by_field_id.insert(field_id, cell_meta); - } + let field_id = changeset.field_id; + let cell_meta = CellMeta { + field_id: field_id.clone(), + data: changeset.data.unwrap_or("".to_owned()), + }; + cell_by_field_id.insert(field_id, cell_meta); RowMetaChangeset { row_id: changeset.row_id, diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 513a1ea9ec..f022488f0a 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -42,6 +42,7 @@ impl GridMetaPad { Self::from_delta(grid_delta) } + #[tracing::instrument(level = "debug", skip_all, err)] pub fn create_field( &mut self, new_field_meta: FieldMeta, @@ -186,7 +187,7 @@ impl GridMetaPad { self.grid_meta.fields.iter().map(FieldOrder::from).collect() } - pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { + pub fn get_field_metas(&self, field_orders: Option>) -> CollaborateResult> { match field_orders { None => Ok(self.grid_meta.fields.clone()), Some(field_orders) => { From 2607822412de6aeadb8ac5ce0aae6971b25df948 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 5 Apr 2022 21:25:59 +0800 Subject: [PATCH 097/179] chore: show selection --- .../grid/cell_bloc/cell_service.dart | 43 ++ .../grid/cell_bloc/selection_cell_bloc.dart | 36 +- .../grid/cell_bloc/selection_editor_bloc.dart | 8 +- .../type_option/type_option_service.dart | 6 +- .../application/grid/row/row_service.dart | 1 - .../cell/selection_cell/selection_cell.dart | 2 +- .../cell/selection_cell/selection_editor.dart | 19 +- .../dart_event/flowy-grid/dart_event.dart | 10 +- .../flowy-grid-data-model/grid.pb.dart | 170 ++--- .../flowy-grid-data-model/grid.pbjson.dart | 29 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../flowy-grid/selection_type_option.pb.dart | 42 +- .../selection_type_option.pbjson.dart | 7 +- .../rust-lib/flowy-grid/src/event_handler.rs | 66 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 20 +- frontend/rust-lib/flowy-grid/src/manager.rs | 1 - .../src/protobuf/model/event_map.rs | 12 +- .../protobuf/model/selection_type_option.rs | 79 ++- .../src/protobuf/proto/event_map.proto | 2 +- .../proto/selection_type_option.proto | 5 +- .../src/services/block_meta_editor.rs | 8 +- .../type_options/checkbox_type_option.rs | 29 +- .../field/type_options/date_type_option.rs | 39 +- .../field/type_options/number_type_option.rs | 57 +- .../type_options/selection_type_option.rs | 194 ++++-- .../field/type_options/text_type_option.rs | 24 +- .../flowy-grid/src/services/grid_editor.rs | 102 ++- .../src/services/persistence/block_index.rs | 1 - .../flowy-grid/src/services/persistence/kv.rs | 1 - .../src/services/row/cell_data_operation.rs | 81 ++- .../src/services/row/row_builder.rs | 6 +- .../flowy-grid/src/services/row/row_loader.rs | 8 +- .../flowy-grid/tests/grid/grid_test.rs | 16 +- .../src/entities/grid.rs | 72 +- .../src/protobuf/model/grid.rs | 619 +++++++++--------- .../src/protobuf/proto/grid.proto | 11 +- .../src/client_grid/grid_meta_pad.rs | 1 - 38 files changed, 1080 insertions(+), 755 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index e1af022d95..f7a0247a98 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,11 +1,54 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; class CellService { CellService(); + Future> addSelectOpiton({ + required String gridId, + required String fieldId, + required String rowId, + required String optionId, + }) { + final payload = SelectOptionChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..insertOptionId = optionId; + return GridEventApplySelectOptionChangeset(payload).send(); + } + + Future> getSelectOpitonContext({ + required String gridId, + required String fieldId, + required String rowId, + }) { + final payload = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + + return GridEventGetSelectOptions(payload).send(); + } + + Future> removeSelectOpiton({ + required String gridId, + required String fieldId, + required String rowId, + required String optionId, + }) { + final payload = SelectOptionChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..deleteOptionId = optionId; + return GridEventApplySelectOptionChangeset(payload).send(); + } + Future> updateCell({ required String gridId, required String fieldId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 2cde7c6a96..1b38376e86 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -11,12 +11,13 @@ import 'cell_service.dart'; part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { - final CellService service; + final CellService _service; SelectionCellBloc({ - required this.service, + required CellService service, required CellData cellData, - }) : super(SelectionCellState.initial(cellData)) { + }) : _service = service, + super(SelectionCellState.initial(cellData)) { on( (event, emit) async { await event.map( @@ -37,30 +38,17 @@ class SelectionCellBloc extends Bloc { } void _loadOptions() async { - final result = await FieldContextLoaderAdaptor( + final result = await _service.getSelectOpitonContext( gridId: state.cellData.gridId, - field: state.cellData.field, - ).load(); + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); result.fold( - (context) { - List options = []; - switch (state.cellData.field.fieldType) { - case FieldType.MultiSelect: - options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options); - break; - case FieldType.SingleSelect: - options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options); - break; - default: - Log.error("Invalid field type, expect single select or multiple select"); - break; - } - - final ids = state.cellData.cell?.content.split(','); - final selectedOptions = ids?.map((id) => options.firstWhere((option) => option.id == id)).toList() ?? []; - add(SelectionCellEvent.didReceiveOptions(options, selectedOptions)); - }, + (selectOptionContext) => add(SelectionCellEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )), (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 5ce68105ea..671dc7ae8a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -41,15 +41,15 @@ class SelectOptionEditorBloc extends Bloc null, (err) => Log.error(err)); }, selectOption: (_SelectOption value) { - _cellService.updateCell( + _cellService.addSelectOpiton( gridId: state.gridId, - fieldId: state.fieldId, + fieldId: state.field.id, rowId: state.rowId, - data: data, + optionId: value.optionId, ); }, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart index 8ab3460b82..9121ded71b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart @@ -10,8 +10,10 @@ class TypeOptionService { required this.fieldId, }); - Future> createOption(String name) { - final payload = CreateSelectOptionPayload.create()..optionName = name; + Future> createOption(String name, {bool selected = false}) { + final payload = CreateSelectOptionPayload.create() + ..optionName = name + ..selected = selected; return GridEventCreateSelectOption(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index a65cb81b29..1b3f9e87ec 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -22,7 +22,6 @@ class RowService { Future> getRow() { QueryRowPayload payload = QueryRowPayload.create() ..gridId = gridId - ..blockId = blockId ..rowId = rowId; return GridEventGetRow(payload).send(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 3fe1b19c14..33a935d37e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -39,7 +39,7 @@ class _SingleSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - SelectionEditor.show(context, state.cellData, state.options, state.selectedOptions); + SelectOptionEditor.show(context, state.cellData, state.options, state.selectedOptions); }, child: Row(children: children), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 0c8d207a4b..d10a5a8cf8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -21,12 +21,12 @@ import 'extension.dart'; const double _editorPannelWidth = 300; -class SelectionEditor extends StatelessWidget { +class SelectOptionEditor extends StatelessWidget { final CellData cellData; final List options; final List selectedOptions; - const SelectionEditor({ + const SelectOptionEditor({ required this.cellData, required this.options, required this.selectedOptions, @@ -34,15 +34,14 @@ class SelectionEditor extends StatelessWidget { }) : super(key: key); static String identifier() { - return (SelectionEditor).toString(); + return (SelectOptionEditor).toString(); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => SelectOptionEditorBloc( - gridId: cellData.gridId, - field: cellData.field, + cellData: cellData, options: options, selectedOptions: selectedOptions, ), @@ -68,8 +67,8 @@ class SelectionEditor extends StatelessWidget { List options, List selectedOptions, ) { - SelectionEditor.hide(context); - final editor = SelectionEditor( + SelectOptionEditor.hide(context); + final editor = SelectOptionEditor( cellData: cellData, options: options, selectedOptions: selectedOptions, @@ -81,7 +80,7 @@ class SelectionEditor extends StatelessWidget { child: SizedBox(width: _editorPannelWidth, child: editor), constraints: BoxConstraints.loose(const Size(_editorPannelWidth, 300)), ), - identifier: SelectionEditor.identifier(), + identifier: SelectOptionEditor.identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomWithCenterAligned, ); @@ -177,7 +176,9 @@ class _SelectOptionCell extends StatelessWidget { return SizedBox( height: GridSize.typeOptionItemHeight, child: InkWell( - onTap: () {}, + onTap: () { + context.read().add(SelectOptionEditorEvent.selectOption(option.id)); + }, child: FlowyHover( config: HoverDisplayConfig(hoverColor: theme.hover), builder: (_, onHover) { 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 a709d06fe8..2a23cfad4a 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 @@ -172,7 +172,7 @@ class GridEventCreateSelectOption { } class GridEventGetSelectOptions { - FieldIdentifierPayload request; + CellIdentifierPayload request; GridEventGetSelectOptions(this.request); Future> send() { @@ -239,13 +239,13 @@ class GridEventUpdateCell { } } -class GridEventInsertSelectOption { - InsertSelectOptionPayload request; - GridEventInsertSelectOption(this.request); +class GridEventApplySelectOptionChangeset { + SelectOptionChangesetPayload request; + GridEventApplySelectOptionChangeset(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.InsertSelectOption.toString() + ..event = GridEvent.ApplySelectOptionChangeset.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) 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 7fcee422d7..ab195308c6 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 @@ -266,67 +266,6 @@ class FieldIdentifierPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(2); } -class FieldIdentifierParams extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldIdentifierParams', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..hasRequiredFields = false - ; - - FieldIdentifierParams._() : super(); - factory FieldIdentifierParams({ - $core.String? fieldId, - $core.String? gridId, - }) { - final _result = create(); - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (gridId != null) { - _result.gridId = gridId; - } - return _result; - } - factory FieldIdentifierParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FieldIdentifierParams.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') - FieldIdentifierParams clone() => FieldIdentifierParams()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FieldIdentifierParams copyWith(void Function(FieldIdentifierParams) updates) => super.copyWith((message) => updates(message as FieldIdentifierParams)) as FieldIdentifierParams; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FieldIdentifierParams create() => FieldIdentifierParams._(); - FieldIdentifierParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static FieldIdentifierParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static FieldIdentifierParams? _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.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); -} - 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') @@ -1085,6 +1024,81 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(2); } +class CellIdentifierPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellIdentifierPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..hasRequiredFields = false + ; + + CellIdentifierPayload._() : super(); + factory CellIdentifierPayload({ + $core.String? gridId, + $core.String? fieldId, + $core.String? rowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (rowId != null) { + _result.rowId = rowId; + } + return _result; + } + factory CellIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellIdentifierPayload.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') + CellIdentifierPayload clone() => CellIdentifierPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellIdentifierPayload copyWith(void Function(CellIdentifierPayload) updates) => super.copyWith((message) => updates(message as CellIdentifierPayload)) as CellIdentifierPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellIdentifierPayload create() => CellIdentifierPayload._(); + CellIdentifierPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellIdentifierPayload? _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 fieldId => $_getSZ(1); + @$pb.TagNumber(2) + set fieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get rowId => $_getSZ(2); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(2); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); +} + class RepeatedCell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedCell', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Cell.create) @@ -1566,7 +1580,6 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage { class QueryRowPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..hasRequiredFields = false ; @@ -1574,16 +1587,12 @@ class QueryRowPayload extends $pb.GeneratedMessage { QueryRowPayload._() : super(); factory QueryRowPayload({ $core.String? gridId, - $core.String? blockId, $core.String? rowId, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (blockId != null) { - _result.blockId = blockId; - } if (rowId != null) { _result.rowId = rowId; } @@ -1619,21 +1628,12 @@ class QueryRowPayload extends $pb.GeneratedMessage { @$pb.TagNumber(1) void clearGridId() => clearField(1); - @$pb.TagNumber(2) - $core.String get blockId => $_getSZ(1); - @$pb.TagNumber(2) - set blockId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasBlockId() => $_has(1); - @$pb.TagNumber(2) - void clearBlockId() => clearField(2); - @$pb.TagNumber(3) - $core.String get rowId => $_getSZ(2); + $core.String get rowId => $_getSZ(1); @$pb.TagNumber(3) - set rowId($core.String v) { $_setString(2, v); } + set rowId($core.String v) { $_setString(1, v); } @$pb.TagNumber(3) - $core.bool hasRowId() => $_has(2); + $core.bool hasRowId() => $_has(1); @$pb.TagNumber(3) void clearRowId() => clearField(3); } @@ -1641,17 +1641,22 @@ class QueryRowPayload extends $pb.GeneratedMessage { class CreateSelectOptionPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'selected') ..hasRequiredFields = false ; CreateSelectOptionPayload._() : super(); factory CreateSelectOptionPayload({ $core.String? optionName, + $core.bool? selected, }) { final _result = create(); if (optionName != null) { _result.optionName = optionName; } + if (selected != null) { + _result.selected = selected; + } return _result; } factory CreateSelectOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -1683,5 +1688,14 @@ class CreateSelectOptionPayload extends $pb.GeneratedMessage { $core.bool hasOptionName() => $_has(0); @$pb.TagNumber(1) void clearOptionName() => clearField(1); + + @$pb.TagNumber(2) + $core.bool get selected => $_getBF(1); + @$pb.TagNumber(2) + set selected($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasSelected() => $_has(1); + @$pb.TagNumber(2) + void clearSelected() => clearField(2); } 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 596c7f6fc1..c51a224a9e 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 @@ -47,17 +47,6 @@ const FieldIdentifierPayload$json = const { /// Descriptor for `FieldIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldIdentifierPayloadDescriptor = $convert.base64Decode('ChZGaWVsZElkZW50aWZpZXJQYXlsb2FkEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZA=='); -@$core.Deprecated('Use fieldIdentifierParamsDescriptor instead') -const FieldIdentifierParams$json = const { - '1': 'FieldIdentifierParams', - '2': const [ - const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, - ], -}; - -/// Descriptor for `FieldIdentifierParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldIdentifierParamsDescriptor = $convert.base64Decode('ChVGaWVsZElkZW50aWZpZXJQYXJhbXMSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElk'); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -214,6 +203,18 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); +@$core.Deprecated('Use cellIdentifierPayloadDescriptor instead') +const CellIdentifierPayload$json = const { + '1': 'CellIdentifierPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + ], +}; + +/// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); @$core.Deprecated('Use repeatedCellDescriptor instead') const RepeatedCell$json = const { '1': 'RepeatedCell', @@ -311,20 +312,20 @@ const QueryRowPayload$json = const { '1': 'QueryRowPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, ], }; /// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); +final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); @$core.Deprecated('Use createSelectOptionPayloadDescriptor instead') const CreateSelectOptionPayload$json = const { '1': 'CreateSelectOptionPayload', '2': const [ const {'1': 'option_name', '3': 1, '4': 1, '5': 9, '10': 'optionName'}, + const {'1': 'selected', '3': 2, '4': 1, '5': 8, '10': 'selected'}, ], }; /// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1l'); +final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1lEhoKCHNlbGVjdGVkGAIgASgIUghzZWxlY3RlZA=='); 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 2de16d922c..4c8cff633b 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 @@ -24,7 +24,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); - static const GridEvent InsertSelectOption = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InsertSelectOption'); + static const GridEvent ApplySelectOptionChangeset = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); static const $core.List values = [ GetGridData, @@ -41,7 +41,7 @@ class GridEvent extends $pb.ProtobufEnum { CreateRow, GetRow, UpdateCell, - InsertSelectOption, + ApplySelectOptionChangeset, ]; 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 56b593c688..017dc4b1aa 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 @@ -26,9 +26,9 @@ const GridEvent$json = const { const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, const {'1': 'UpdateCell', '2': 70}, - const {'1': 'InsertSelectOption', '2': 71}, + const {'1': 'ApplySelectOptionChangeset', '2': 71}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEhQKEEdldFNlbGVjdE9wdGlvbnMQHxINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxIOCgpVcGRhdGVDZWxsEEYSFgoSSW5zZXJ0U2VsZWN0T3B0aW9uEEc='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEhQKEEdldFNlbGVjdE9wdGlvbnMQHxINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxIOCgpVcGRhdGVDZWxsEEYSHgoaQXBwbHlTZWxlY3RPcHRpb25DaGFuZ2VzZXQQRw=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart index 2b9fc8a5ce..350806f275 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -210,20 +210,21 @@ enum SelectOptionChangesetPayload_OneOfDeleteOptionId { class SelectOptionChangesetPayload extends $pb.GeneratedMessage { static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfInsertOptionId> _SelectOptionChangesetPayload_OneOfInsertOptionIdByTag = { - 3 : SelectOptionChangesetPayload_OneOfInsertOptionId.insertOptionId, + 4 : SelectOptionChangesetPayload_OneOfInsertOptionId.insertOptionId, 0 : SelectOptionChangesetPayload_OneOfInsertOptionId.notSet }; static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfDeleteOptionId> _SelectOptionChangesetPayload_OneOfDeleteOptionIdByTag = { - 4 : SelectOptionChangesetPayload_OneOfDeleteOptionId.deleteOptionId, + 5 : SelectOptionChangesetPayload_OneOfDeleteOptionId.deleteOptionId, 0 : SelectOptionChangesetPayload_OneOfDeleteOptionId.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionChangesetPayload', createEmptyInstance: create) - ..oo(0, [3]) - ..oo(1, [4]) + ..oo(0, [4]) + ..oo(1, [5]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') ..hasRequiredFields = false ; @@ -231,6 +232,7 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { factory SelectOptionChangesetPayload({ $core.String? gridId, $core.String? rowId, + $core.String? fieldId, $core.String? insertOptionId, $core.String? deleteOptionId, }) { @@ -241,6 +243,9 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { if (rowId != null) { _result.rowId = rowId; } + if (fieldId != null) { + _result.fieldId = fieldId; + } if (insertOptionId != null) { _result.insertOptionId = insertOptionId; } @@ -295,22 +300,31 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { void clearRowId() => clearField(2); @$pb.TagNumber(3) - $core.String get insertOptionId => $_getSZ(2); + $core.String get fieldId => $_getSZ(2); @$pb.TagNumber(3) - set insertOptionId($core.String v) { $_setString(2, v); } + set fieldId($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasInsertOptionId() => $_has(2); + $core.bool hasFieldId() => $_has(2); @$pb.TagNumber(3) - void clearInsertOptionId() => clearField(3); + void clearFieldId() => clearField(3); @$pb.TagNumber(4) - $core.String get deleteOptionId => $_getSZ(3); + $core.String get insertOptionId => $_getSZ(3); @$pb.TagNumber(4) - set deleteOptionId($core.String v) { $_setString(3, v); } + set insertOptionId($core.String v) { $_setString(3, v); } @$pb.TagNumber(4) - $core.bool hasDeleteOptionId() => $_has(3); + $core.bool hasInsertOptionId() => $_has(3); @$pb.TagNumber(4) - void clearDeleteOptionId() => clearField(4); + void clearInsertOptionId() => clearField(4); + + @$pb.TagNumber(5) + $core.String get deleteOptionId => $_getSZ(4); + @$pb.TagNumber(5) + set deleteOptionId($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasDeleteOptionId() => $_has(4); + @$pb.TagNumber(5) + void clearDeleteOptionId() => clearField(5); } class SelectOptionContext extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart index 4002db9a33..04c44a3004 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -66,8 +66,9 @@ const SelectOptionChangesetPayload$json = const { '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': 'insert_option_id', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'insertOptionId'}, - const {'1': 'delete_option_id', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'deleteOptionId'}, + const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'insert_option_id', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'insertOptionId'}, + const {'1': 'delete_option_id', '3': 5, '4': 1, '5': 9, '9': 1, '10': 'deleteOptionId'}, ], '8': const [ const {'1': 'one_of_insert_option_id'}, @@ -76,7 +77,7 @@ const SelectOptionChangesetPayload$json = const { }; /// Descriptor for `SelectOptionChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEioKEGluc2VydF9vcHRpb25faWQYAyABKAlIAFIOaW5zZXJ0T3B0aW9uSWQSKgoQZGVsZXRlX29wdGlvbl9pZBgEIAEoCUgBUg5kZWxldGVPcHRpb25JZEIZChdvbmVfb2ZfaW5zZXJ0X29wdGlvbl9pZEIZChdvbmVfb2ZfZGVsZXRlX29wdGlvbl9pZA=='); +final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEioKEGluc2VydF9vcHRpb25faWQYBCABKAlIAFIOaW5zZXJ0T3B0aW9uSWQSKgoQZGVsZXRlX29wdGlvbl9pZBgFIAEoCUgBUg5kZWxldGVPcHRpb25JZEIZChdvbmVfb2ZfaW5zZXJ0X29wdGlvbl9pZEIZChdvbmVfb2ZfZGVsZXRlX29wdGlvbl9pZA=='); @$core.Deprecated('Use selectOptionContextDescriptor instead') const SelectOptionContext$json = const { '1': 'SelectOptionContext', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index dd7675e803..62cbb4abec 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,7 @@ use crate::manager::GridManager; use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_json_str, SelectOption, - SelectOptionChangesetParams, SelectOptionChangesetPayload, + default_type_option_builder_from_type, type_option_builder_from_json_str, MultiSelectTypeOption, SelectOption, + SelectOptionChangesetParams, SelectOptionChangesetPayload, SelectOptionContext, SingleSelectTypeOption, }; use crate::services::grid_editor::ClientGridEditor; use flowy_error::{FlowyError, FlowyResult}; @@ -93,7 +93,10 @@ pub(crate) async fn switch_to_field_handler( .switch_to_field_type(¶ms.field_id, ¶ms.field_type) .await?; - let field_meta = editor.get_field(¶ms.field_id).await?; + let field_meta = editor + .get_field_metas(Some(vec![params.field_id.as_str()])) + .await? + .pop(); let edit_context = make_field_edit_context( ¶ms.grid_id, Some(params.field_id), @@ -124,6 +127,44 @@ pub(crate) async fn create_select_option_handler( data_result(SelectOption::new(¶ms.option_name)) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn get_select_option_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CellIdentifierParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor + .get_field_metas(Some(vec![params.field_id.as_str()])) + .await? + .pop() + { + None => { + tracing::error!("Can't find the corresponding field with id: {}", params.field_id); + data_result(SelectOptionContext::default()) + } + Some(field_meta) => { + let cell_meta = editor.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; + match field_meta.field_type { + FieldType::SingleSelect => { + let type_option = SingleSelectTypeOption::from(&field_meta); + let select_option_context = type_option.select_option_context(&cell_meta); + data_result(select_option_context) + } + FieldType::MultiSelect => { + let type_option = MultiSelectTypeOption::from(&field_meta); + let select_option_context = type_option.select_option_context(&cell_meta); + data_result(select_option_context) + } + ty => { + tracing::error!("Unsupported field type: {:?} for this handler", ty); + data_result(SelectOptionContext::default()) + } + } + } + } +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_field_context_handler( data: Data, @@ -164,13 +205,13 @@ async fn get_or_create_field_meta( field_type: &FieldType, editor: Arc, ) -> FlowyResult { - if field_id.is_some() { - if let Some(field_meta) = editor.get_field(field_id.as_ref().unwrap()).await? { - return Ok(field_meta); - } + match field_id { + None => editor.create_next_field_meta(field_type).await, + Some(field_id) => match editor.get_field_metas(Some(vec![field_id.as_str()])).await?.pop() { + None => editor.create_next_field_meta(field_type).await, + Some(field_meta) => Ok(field_meta), + }, } - - editor.create_next_field_meta(field_type).await } #[tracing::instrument(level = "debug", skip(data, manager), err)] @@ -180,7 +221,7 @@ pub(crate) async fn get_row_handler( ) -> DataResult { let params: QueryRowParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - match editor.get_row(¶ms.block_id, ¶ms.row_id).await? { + match editor.get_row(¶ms.row_id).await? { None => Err(FlowyError::record_not_found().context("Can not find the row")), Some(row) => data_result(row), } @@ -209,12 +250,13 @@ pub(crate) async fn update_cell_handler( } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn insert_select_option_handler( +pub(crate) async fn apply_select_option_changeset_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { let params: SelectOptionChangesetParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let _ = editor.insert_select_option(params).await?; + let changeset: CellMetaChangeset = params.into(); + let _ = editor.update_cell(changeset).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 64c7c70e56..2af4b28e35 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -10,18 +10,26 @@ pub fn create(grid_manager: Arc) -> Module { module = module .event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) + // Field .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) .event(GridEvent::DeleteField, delete_field_handler) .event(GridEvent::SwitchToField, switch_to_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) - .event(GridEvent::GetEditFieldContext, get_field_context_handler) - .event(GridEvent::CreateSelectOption, create_select_option_handler) + // Row .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) + // Cell .event(GridEvent::UpdateCell, update_cell_handler) - .event(GridEvent::InsertSelectOption, insert_select_option_handler); + // SelectOption + .event(GridEvent::CreateSelectOption, create_select_option_handler) + .event(GridEvent::GetSelectOptions, get_select_option_handler) + .event( + GridEvent::ApplySelectOptionChangeset, + apply_select_option_changeset_handler, + ) + .event(GridEvent::GetEditFieldContext, get_field_context_handler); module } @@ -59,7 +67,7 @@ pub enum GridEvent { #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] CreateSelectOption = 30, - #[event(input = "FieldIdentifierPayload", output = "SelectOptionContext")] + #[event(input = "CellIdentifierPayload", output = "SelectOptionContext")] GetSelectOptions = 31, #[event(input = "CreateRowPayload", output = "Row")] @@ -71,6 +79,6 @@ pub enum GridEvent { #[event(input = "CellMetaChangeset")] UpdateCell = 70, - #[event(input = "InsertSelectOptionPayload")] - InsertSelectOption = 71, + #[event(input = "SelectOptionChangesetPayload")] + ApplySelectOptionChangeset = 71, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 686f539b74..d82b2950da 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -12,7 +12,6 @@ use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use flowy_sync::client_grid::{make_block_meta_delta, make_grid_delta}; use flowy_sync::entities::revision::{RepeatedRevision, Revision}; use std::sync::Arc; -use tokio::sync::RwLock; pub trait GridUser: Send + Sync { fn user_id(&self) -> Result; 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 ae1dfe161d..72a0601391 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 @@ -39,7 +39,7 @@ pub enum GridEvent { CreateRow = 50, GetRow = 51, UpdateCell = 70, - InsertSelectOption = 71, + ApplySelectOptionChangeset = 71, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -63,7 +63,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), 70 => ::std::option::Option::Some(GridEvent::UpdateCell), - 71 => ::std::option::Option::Some(GridEvent::InsertSelectOption), + 71 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), _ => ::std::option::Option::None } } @@ -84,7 +84,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, - GridEvent::InsertSelectOption, + GridEvent::ApplySelectOptionChangeset, ]; values } @@ -113,14 +113,14 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xa2\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xaa\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x16\n\x12Creat\ eSelectOption\x10\x1e\x12\x14\n\x10GetSelectOptions\x10\x1f\x12\r\n\tCre\ - ateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\x16\n\ - \x12InsertSelectOption\x10Gb\x06proto3\ + ateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\x1e\n\ + \x1aApplySelectOptionChangeset\x10Gb\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/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index ba0e1bebe9..7a65da1171 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -662,6 +662,7 @@ pub struct SelectOptionChangesetPayload { // message fields pub grid_id: ::std::string::String, pub row_id: ::std::string::String, + pub field_id: ::std::string::String, // message oneof groups pub one_of_insert_option_id: ::std::option::Option, pub one_of_delete_option_id: ::std::option::Option, @@ -743,7 +744,33 @@ impl SelectOptionChangesetPayload { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } - // string insert_option_id = 3; + // 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 insert_option_id = 4; pub fn get_insert_option_id(&self) -> &str { @@ -792,7 +819,7 @@ impl SelectOptionChangesetPayload { } } - // string delete_option_id = 4; + // string delete_option_id = 5; pub fn get_delete_option_id(&self) -> &str { @@ -858,12 +885,15 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); }, - 4 => { + 5 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -887,17 +917,20 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { 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 ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { - my_size += ::protobuf::rt::string_size(3, &v); + my_size += ::protobuf::rt::string_size(4, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { - my_size += ::protobuf::rt::string_size(4, &v); + my_size += ::protobuf::rt::string_size(5, &v); }, }; } @@ -913,17 +946,20 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { 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 ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { - os.write_string(3, v)?; + os.write_string(4, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { - os.write_string(4, v)?; + os.write_string(5, v)?; }, }; } @@ -975,6 +1011,11 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { |m: &SelectOptionChangesetPayload| { &m.row_id }, |m: &mut SelectOptionChangesetPayload| { &mut m.row_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &SelectOptionChangesetPayload| { &m.field_id }, + |m: &mut SelectOptionChangesetPayload| { &mut m.field_id }, + )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "insert_option_id", SelectOptionChangesetPayload::has_insert_option_id, @@ -1003,6 +1044,7 @@ impl ::protobuf::Clear for SelectOptionChangesetPayload { fn clear(&mut self) { self.grid_id.clear(); self.row_id.clear(); + self.field_id.clear(); self.one_of_insert_option_id = ::std::option::Option::None; self.one_of_delete_option_id = ::std::option::Option::None; self.unknown_fields.clear(); @@ -1315,18 +1357,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\ s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"\\\n\x0cS\ electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ \x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\x18\x03\x20\x01(\x0e2\x12.S\ - electOptionColorR\x05color\"\xdc\x01\n\x1cSelectOptionChangesetPayload\ + electOptionColorR\x05color\"\xf7\x01\n\x1cSelectOptionChangesetPayload\ \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ - \x18\x02\x20\x01(\tR\x05rowId\x12*\n\x10insert_option_id\x18\x03\x20\x01\ - (\tH\0R\x0einsertOptionId\x12*\n\x10delete_option_id\x18\x04\x20\x01(\tH\ - \x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_\ - of_delete_option_id\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\ - \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\n\x0eselect_options\ - \x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOptions*y\n\x11SelectOptio\ - nColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightP\ - ink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\ - \n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\ - \x12\x08\n\x04Blue\x10\x08b\x06proto3\ + \x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\ + \x07fieldId\x12*\n\x10insert_option_id\x18\x04\x20\x01(\tH\0R\x0einsertO\ + ptionId\x12*\n\x10delete_option_id\x18\x05\x20\x01(\tH\x01R\x0edeleteOpt\ + ionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_of_delete_option_i\ + d\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.\ + SelectOptionR\x07options\x124\n\x0eselect_options\x18\x02\x20\x03(\x0b2\ + \r.SelectOptionR\rselectOptions*y\n\x11SelectOptionColor\x12\n\n\x06Purp\ + le\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightPink\x10\x02\x12\n\n\ + \x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\n\x04Lime\x10\x05\ + \x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\x12\x08\n\x04Blue\ + \x10\x08b\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 4703711cb3..b423fee748 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 @@ -15,5 +15,5 @@ enum GridEvent { CreateRow = 50; GetRow = 51; UpdateCell = 70; - InsertSelectOption = 71; + ApplySelectOptionChangeset = 71; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index 37dc0a36c1..3431373504 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -16,8 +16,9 @@ message SelectOption { message SelectOptionChangesetPayload { string grid_id = 1; string row_id = 2; - oneof one_of_insert_option_id { string insert_option_id = 3; }; - oneof one_of_delete_option_id { string delete_option_id = 4; }; + string field_id = 3; + oneof one_of_insert_option_id { string insert_option_id = 4; }; + oneof one_of_delete_option_id { string delete_option_id = 5; }; } message SelectOptionContext { repeated SelectOption options = 1; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index c5082a1c2e..abdf1d5cbe 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -22,9 +22,6 @@ use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; -type RowId = String; -type BlockId = String; - pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, @@ -145,6 +142,11 @@ impl GridBlockMetaEditorManager { for block_id in block_ids { let editor = self.get_editor(&block_id).await?; let row_metas = editor.get_row_metas(None).await?; + + row_metas.iter().for_each(|row| { + let _ = self.persistence.insert_or_update(&row.block_id, &row.id); + }); + snapshots.push(GridBlockSnapshot { block_id, row_metas }); } Ok(snapshots) diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index b91409c904..2afdadb2f4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -41,7 +41,7 @@ const YES: &str = "Yes"; const NO: &str = "No"; impl CellDataOperation for CheckboxTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_text() || !type_option_cell_data.is_checkbox() { return String::new(); @@ -55,8 +55,13 @@ impl CellDataOperation for CheckboxTypeOption { String::new() } - fn serialize_cell_data(&self, data: &str) -> Result { - let s = match string_to_bool(data) { + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let s = match string_to_bool(&changeset) { true => YES, false => NO, }; @@ -89,16 +94,16 @@ mod tests { let type_option = CheckboxTypeOption::default(); let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); - assert_eq!(type_option.serialize_cell_data("true").unwrap(), "1".to_owned()); - assert_eq!(type_option.serialize_cell_data("1").unwrap(), "1".to_owned()); - assert_eq!(type_option.serialize_cell_data("yes").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("true").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("1").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("yes").unwrap(), "1".to_owned()); - assert_eq!(type_option.serialize_cell_data("false").unwrap(), "0".to_owned()); - assert_eq!(type_option.serialize_cell_data("no").unwrap(), "0".to_owned()); - assert_eq!(type_option.serialize_cell_data("123").unwrap(), "0".to_owned()); + assert_eq!(type_option.apply_changeset("false").unwrap(), "0".to_owned()); + assert_eq!(type_option.apply_changeset("no").unwrap(), "0".to_owned()); + assert_eq!(type_option.apply_changeset("123").unwrap(), "0".to_owned()); assert_eq!( - type_option.deserialize_cell_data("1".to_owned(), &field_meta), + type_option.decode_cell_data("1".to_owned(), &field_meta), "1".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 2c67c69fe5..6472b91bb7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,11 +1,11 @@ use crate::impl_type_option; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; 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::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -43,7 +43,7 @@ impl DateTypeOption { } impl CellDataOperation for DateTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_date() { return String::new(); @@ -63,13 +63,18 @@ impl CellDataOperation for DateTypeOption { String::new() } - fn serialize_cell_data(&self, data: &str) -> Result { - if let Err(e) = data.parse::() { - tracing::error!("Parse {} to i64 failed: {}", data, e); + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + if let Err(e) = changeset.parse::() { + tracing::error!("Parse {} to i64 failed: {}", changeset.to_string(), e); return Err(FlowyError::internal().context(e)); }; - Ok(TypeOptionCellData::new(data, self.field_type()).json()) + Ok(TypeOptionCellData::new(changeset, self.field_type()).json()) } } @@ -195,7 +200,7 @@ mod tests { let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); assert_eq!( "".to_owned(), - type_option.deserialize_cell_data("1e".to_owned(), &field_meta) + type_option.decode_cell_data("1e".to_owned(), &field_meta) ); } @@ -209,33 +214,33 @@ mod tests { DateFormat::Friendly => { assert_eq!( "Mar 14,2022 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - type_option.deserialize_cell_data(data("Mar 14,2022 17:56"), &field_meta) + type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) ); } DateFormat::US => { assert_eq!( "2022/03/14 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); assert_eq!( "2022/03/14 17:56".to_owned(), - type_option.deserialize_cell_data(data("2022/03/14 17:56"), &field_meta) + type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) ); } DateFormat::ISO => { assert_eq!( "2022-03-14 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } DateFormat::Local => { assert_eq!( "2022/03/14 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } } @@ -256,7 +261,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } TimeFormat::TwelveHour => { @@ -266,7 +271,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 05:56:02 PM".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } } @@ -277,7 +282,7 @@ mod tests { #[should_panic] fn date_description_invalid_data_test() { let type_option = DateTypeOption::default(); - type_option.serialize_cell_data("he").unwrap(); + type_option.apply_changeset("he").unwrap(); } fn data(s: &str) -> String { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 55ce729a7f..b0b5967a9d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -1,8 +1,8 @@ use crate::impl_type_option; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use lazy_static::lazy_static; use rust_decimal::Decimal; @@ -77,7 +77,7 @@ pub struct NumberTypeOption { impl_type_option!(NumberTypeOption, FieldType::Number); impl CellDataOperation for NumberTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() { return String::new(); @@ -101,8 +101,13 @@ impl CellDataOperation for NumberTypeOption { } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = self.strip_symbol(data); + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let data = self.strip_symbol(changeset); if !data.chars().all(char::is_numeric) { return Err(FlowyError::invalid_data().context("Should only contain numbers")); @@ -149,8 +154,8 @@ impl NumberTypeOption { } } - fn strip_symbol(&self, s: &str) -> String { - let mut s = String::from(s); + fn strip_symbol(&self, s: T) -> String { + let mut s = s.to_string(); if !s.chars().all(char::is_numeric) { s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); } @@ -213,11 +218,8 @@ mod tests { fn number_description_invalid_input_test() { let type_option = NumberTypeOption::default(); let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - assert_eq!("".to_owned(), type_option.deserialize_cell_data(data(""), &field_meta)); - assert_eq!( - "".to_owned(), - type_option.deserialize_cell_data(data("abc"), &field_meta) - ); + assert_eq!("".to_owned(), type_option.decode_cell_data(data(""), &field_meta)); + assert_eq!("".to_owned(), type_option.decode_cell_data(data("abc"), &field_meta)); } #[test] @@ -233,30 +235,27 @@ mod tests { match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "$18,443".to_owned() ); - assert_eq!(type_option.deserialize_cell_data(data(""), &field_meta), "".to_owned()); - assert_eq!( - type_option.deserialize_cell_data(data("abc"), &field_meta), - "".to_owned() - ); + assert_eq!(type_option.decode_cell_data(data(""), &field_meta), "".to_owned()); + assert_eq!(type_option.decode_cell_data(data("abc"), &field_meta), "".to_owned()); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "€18.443".to_owned() ); } @@ -281,25 +280,25 @@ mod tests { match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "$1,844.3".to_owned() ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "¥1,844.3".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "€1.844,3".to_owned() ); } @@ -320,25 +319,25 @@ mod tests { match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "-$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "-¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "-€18.443".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 1774b12ce3..07bef42e5f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,11 +1,13 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{ + CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry, +}; use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; @@ -25,26 +27,66 @@ pub struct SingleSelectTypeOption { } impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); +impl SingleSelectTypeOption { + pub fn select_option_context(&self, cell_meta: &Option) -> SelectOptionContext { + let select_options = make_select_context_from(cell_meta, &self.options); + SelectOptionContext { + options: self.options.clone(), + select_options, + } + } +} + +fn make_select_context_from(cell_meta: &Option, options: &Vec) -> Vec { + match cell_meta { + None => vec![], + Some(cell_meta) => { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&cell_meta.data) { + select_option_ids(type_option_cell_data.data) + .into_iter() + .flat_map(|option_id| options.iter().find(|option| option.id == option_id).cloned()) + .collect() + } else { + vec![] + } + } + } +} + impl CellDataOperation for SingleSelectTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { - if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { + if !type_option_cell_data.is_single_select() { return String::new(); } - let option_id = type_option_cell_data.data; - match self.options.iter().find(|option| option.id == option_id) { + match select_option_ids(type_option_cell_data.data).pop() { None => String::new(), - Some(option) => option.name.clone(), + Some(option_id) => match self.options.iter().find(|option| option.id == option_id) { + None => String::new(), + Some(option) => option.name.clone(), + }, } } else { String::new() } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = single_select_option_id_from_data(data.to_owned())?; - Ok(TypeOptionCellData::new(&data, self.field_type()).json()) + fn apply_changeset>( + &self, + changeset: T, + _cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let select_option_changeset: SelectOptionChangeset = serde_json::from_str(&changeset)?; + let new_cell_data: String; + if let Some(insert_option_id) = select_option_changeset.insert_option_id { + new_cell_data = insert_option_id; + } else { + new_cell_data = "".to_string() + } + + return Ok(TypeOptionCellData::new(&new_cell_data, self.field_type()).json()); } } @@ -81,33 +123,59 @@ pub struct MultiSelectTypeOption { } impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); +impl MultiSelectTypeOption { + pub fn select_option_context(&self, cell_meta: &Option) -> SelectOptionContext { + todo!() + } +} + impl CellDataOperation for MultiSelectTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { - if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { + if !type_option_cell_data.is_multi_select() { return String::new(); } - - match select_option_ids(type_option_cell_data.data) { - Ok(option_ids) => { - // - self.options - .iter() - .filter(|option| option_ids.contains(&option.id)) - .map(|option| option.name.clone()) - .collect::>() - .join(SELECTION_IDS_SEPARATOR) - } - Err(_) => String::new(), - } + let option_ids = select_option_ids(type_option_cell_data.data); + self.options + .iter() + .filter(|option| option_ids.contains(&option.id)) + .map(|option| option.name.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR) } else { String::new() } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = multi_select_option_id_from_data(data.to_owned())?; - Ok(TypeOptionCellData::new(&data, self.field_type()).json()) + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let select_option_changeset: SelectOptionChangeset = serde_json::from_str(&changeset)?; + let new_cell_data: String; + match cell_meta { + None => { + new_cell_data = select_option_changeset + .insert_option_id + .unwrap_or_else(|| "".to_owned()); + } + Some(cell_meta) => { + let mut selected_options = select_option_ids(cell_meta.data); + if let Some(insert_option_id) = select_option_changeset.insert_option_id { + selected_options.push(insert_option_id); + } + + if let Some(delete_option_id) = select_option_changeset.delete_option_id { + selected_options.retain(|id| id != &delete_option_id); + } + + new_cell_data = selected_options.join(SELECTION_IDS_SEPARATOR); + } + } + + Ok(TypeOptionCellData::new(&new_cell_data, self.field_type()).json()) } } @@ -132,41 +200,10 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder { } } -fn single_select_option_id_from_data(data: String) -> FlowyResult { - let select_option_ids = select_option_ids(data)?; - if select_option_ids.is_empty() { - return Ok("".to_owned()); - } - - Ok(select_option_ids.split_first().unwrap().0.to_string()) -} - -fn multi_select_option_id_from_data(data: String) -> FlowyResult { - let select_option_ids = select_option_ids(data)?; - Ok(select_option_ids.join(SELECTION_IDS_SEPARATOR)) -} - -fn select_option_ids(mut data: String) -> FlowyResult> { - data.retain(|c| !c.is_whitespace()); - let select_option_ids = data.split(SELECTION_IDS_SEPARATOR).collect::>(); - if select_option_ids - .par_iter() - .find_first(|option_id| match Uuid::parse_str(option_id) { - Ok(_) => false, - Err(e) => { - tracing::error!("{}", e); - true - } - }) - .is_some() - { - let msg = format!( - "Invalid selection id string: {}. It should consist of the uuid string and separated by comma", - data - ); - return Err(FlowyError::internal().context(msg)); - } - Ok(select_option_ids.iter().map(|id| id.to_string()).collect::>()) +fn select_option_ids(data: String) -> Vec { + data.split(SELECTION_IDS_SEPARATOR) + .map(|id| id.to_string()) + .collect::>() } #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] @@ -209,7 +246,6 @@ pub struct SelectOptionChangesetPayload { pub delete_option_id: Option, } -#[derive(Clone)] pub struct SelectOptionChangesetParams { pub grid_id: String, pub field_id: String, @@ -218,6 +254,28 @@ pub struct SelectOptionChangesetParams { pub delete_option_id: Option, } +#[derive(Clone, Serialize, Deserialize)] +pub struct SelectOptionChangeset { + pub insert_option_id: Option, + pub delete_option_id: Option, +} + +impl std::convert::From for CellMetaChangeset { + fn from(params: SelectOptionChangesetParams) -> Self { + let changeset = SelectOptionChangeset { + insert_option_id: params.insert_option_id, + delete_option_id: params.delete_option_id, + }; + let s = serde_json::to_string(&changeset).unwrap(); + CellMetaChangeset { + grid_id: params.grid_id, + row_id: params.row_id, + field_id: params.field_id, + data: Some(s), + } + } +} + impl TryInto for SelectOptionChangesetPayload { type Error = ErrorCode; @@ -228,7 +286,7 @@ impl TryInto for SelectOptionChangesetPayload { let insert_option_id = match self.insert_option_id { None => None, Some(insert_option_id) => Some( - NotEmptyStr::parse(insert_option_id) + NotEmptyUuid::parse(insert_option_id) .map_err(|_| ErrorCode::OptionIdIsEmpty)? .0, ), @@ -237,7 +295,7 @@ impl TryInto for SelectOptionChangesetPayload { let delete_option_id = match self.delete_option_id { None => None, Some(delete_option_id) => Some( - NotEmptyStr::parse(delete_option_id) + NotEmptyUuid::parse(delete_option_id) .map_err(|_| ErrorCode::OptionIdIsEmpty)? .0, ), @@ -291,9 +349,9 @@ mod tests { #[should_panic] fn selection_description_test() { let type_option = SingleSelectTypeOption::default(); - assert_eq!(type_option.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("1,2,3").unwrap(), "1".to_owned()); let type_option = MultiSelectTypeOption::default(); - assert_eq!(type_option.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + assert_eq!(type_option.apply_changeset("1,2,3").unwrap(), "1,2,3".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 4b7195a305..f38f24ac9d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{deserialize_cell_data, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{decode_cell_data, CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -31,14 +31,14 @@ pub struct RichTextTypeOption { impl_type_option!(RichTextTypeOption, FieldType::RichText); impl CellDataOperation for RichTextTypeOption { - fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() || type_option_cell_data.is_single_select() || type_option_cell_data.is_multi_select() || type_option_cell_data.is_number() { - deserialize_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned()) + decode_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned()) } else { type_option_cell_data.data } @@ -47,8 +47,12 @@ impl CellDataOperation for RichTextTypeOption { } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = data.to_owned(); + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let data = changeset.into(); if data.len() > 10000 { Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) } else { @@ -72,7 +76,7 @@ mod tests { let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); assert_eq!( - type_option.deserialize_cell_data(data, &date_time_field_meta), + type_option.decode_cell_data(data, &date_time_field_meta), "Mar 14,2022 17:56".to_owned() ); @@ -83,7 +87,7 @@ mod tests { let single_select_field_meta = FieldBuilder::new(single_select).build(); let data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); assert_eq!( - type_option.deserialize_cell_data(data, &single_select_field_meta), + type_option.decode_cell_data(data, &single_select_field_meta), "Done".to_owned() ); @@ -103,7 +107,7 @@ mod tests { ) .json(); assert_eq!( - type_option.deserialize_cell_data(data, &multi_select_field_meta), + type_option.decode_cell_data(data, &multi_select_field_meta), "Google,Facebook".to_owned() ); @@ -112,7 +116,7 @@ mod tests { let number_field_meta = FieldBuilder::new(number).build(); let data = TypeOptionCellData::new("18443", FieldType::Number).json(); assert_eq!( - type_option.deserialize_cell_data(data, &number_field_meta), + type_option.decode_cell_data(data, &number_field_meta), "$18,443".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 708e07fd74..17fb852e07 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,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder, SelectOptionChangesetParams, -}; +use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; use bytes::Bytes; @@ -40,7 +38,7 @@ impl ClientGridEditor { let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); let pad = Arc::new(RwLock::new(grid_pad)); - let blocks = pad.read().await.get_block_metas().clone(); + let blocks = pad.read().await.get_block_metas(); let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, blocks, persistence).await?); Ok(Arc::new(Self { @@ -100,7 +98,7 @@ impl ClientGridEditor { pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let field_id = params.field_id.clone(); - let deserializer = match self.pad.read().await.get_field(¶ms.field_id) { + let deserializer = match self.pad.read().await.get_field(params.field_id.as_str()) { None => return Err(ErrorCode::FieldDoesNotExist.into()), Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()), }; @@ -147,11 +145,27 @@ impl ClientGridEditor { Ok(()) } - pub async fn get_field(&self, field_id: &str) -> FlowyResult> { - match self.pad.read().await.get_field(field_id) { - None => Ok(None), - Some(field_meta) => Ok(Some(field_meta.clone())), + pub async fn get_field_metas(&self, field_orders: Option>) -> FlowyResult> + where + T: Into, + { + if field_orders.is_none() { + let field_metas = self.pad.read().await.get_field_metas(None)?; + return Ok(field_metas); } + + let to_field_orders = |item: Vec| item.into_iter().map(|data| data.into()).collect(); + let field_orders = field_orders.map_or(vec![], to_field_orders); + let expected_len = field_orders.len(); + let field_metas = self.pad.read().await.get_field_metas(Some(field_orders))?; + if expected_len != 0 && field_metas.len() != expected_len { + tracing::error!( + "This is a bug. The len of the field_metas should equal to {}", + expected_len + ); + debug_assert!(field_metas.len() == expected_len); + } + Ok(field_metas) } pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { @@ -217,7 +231,7 @@ impl ClientGridEditor { debug_assert_eq!(grid_block_snapshot.len(), 1); if grid_block_snapshot.len() == 1 { let snapshot = grid_block_snapshot.pop().unwrap(); - let field_metas = self.get_field_metas(None).await?; + let field_metas = self.get_field_metas::(None).await?; let rows = make_rows_from_row_metas(&field_metas, &snapshot.row_metas); Ok(rows.into()) } else { @@ -229,7 +243,7 @@ impl ClientGridEditor { match self.block_meta_manager.get_row_meta(row_id).await? { None => Ok(None), Some(row_meta) => { - let field_metas = self.get_field_metas(None).await?; + let field_metas = self.get_field_metas::(None).await?; let row_metas = vec![row_meta]; let mut rows = make_rows_from_row_metas(&field_metas, &row_metas); debug_assert!(rows.len() == 1); @@ -249,32 +263,30 @@ impl ClientGridEditor { } } - pub async fn apply_select_option(&self, params: SelectOptionChangesetParams) -> FlowyResult<()> { - let cell_meta = self.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; - todo!() - } - pub async fn update_cell(&self, mut changeset: CellMetaChangeset) -> FlowyResult<()> { - if let Some(cell_data) = changeset.data.as_ref() { - match self.pad.read().await.get_field(&changeset.field_id) { - None => { - let msg = format!("Can not find the field with id: {}", &changeset.field_id); - return Err(FlowyError::internal().context(msg)); - } - Some(field_meta) => { - let cell_data = serialize_cell_data(cell_data, field_meta)?; - changeset.data = Some(cell_data); - } - } + if changeset.data.as_ref().is_none() { + return Ok(()); } - let field_metas = self.get_field_metas(None).await?; - let row_changeset: RowMetaChangeset = changeset.into(); - let _ = self - .block_meta_manager - .update_row_cells(&field_metas, row_changeset) - .await?; - Ok(()) + let cell_data_changeset = changeset.data.unwrap(); + let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?; + match self.pad.read().await.get_field(&changeset.field_id) { + None => { + let msg = format!("Field not found with id: {}", &changeset.field_id); + return Err(FlowyError::internal().context(msg)); + } + Some(field_meta) => { + // Update the changeset.data property with the return value. + changeset.data = Some(apply_cell_data_changeset(cell_data_changeset, cell_meta, field_meta)?); + let field_metas = self.get_field_metas::(None).await?; + let row_changeset: RowMetaChangeset = changeset.into(); + let _ = self + .block_meta_manager + .update_row_cells(&field_metas, row_changeset) + .await?; + Ok(()) + } + } } pub async fn get_blocks(&self, block_ids: Option>) -> FlowyResult { @@ -314,23 +326,6 @@ impl ClientGridEditor { }) } - pub async fn get_field_metas(&self, field_orders: Option>) -> FlowyResult> { - let expected_len = match field_orders.as_ref() { - None => 0, - Some(field_orders) => field_orders.len(), - }; - - let field_metas = self.pad.read().await.get_field_metas(field_orders)?; - if expected_len != 0 && field_metas.len() != expected_len { - tracing::error!( - "This is a bug. The len of the field_metas should equal to {}", - expected_len - ); - debug_assert!(field_metas.len() == expected_len); - } - Ok(field_metas) - } - pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { let block_ids = match block_ids { None => self @@ -393,7 +388,7 @@ impl ClientGridEditor { } async fn notify_did_update_fields(&self) -> FlowyResult<()> { - let field_metas = self.get_field_metas(None).await?; + let field_metas = self.get_field_metas::(None).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); send_dart_notification(&self.grid_id, GridNotification::DidUpdateFields) .payload(repeated_field) @@ -402,8 +397,7 @@ impl ClientGridEditor { } async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { - let field_order = FieldOrder::from(field_id); - let mut field_metas = self.get_field_metas(Some(field_order.into())).await?; + let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; debug_assert!(field_metas.len() == 1); if let Some(field_meta) = field_metas.pop() { diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs index a639776394..df75ec629c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs @@ -3,7 +3,6 @@ use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; use flowy_database::{ prelude::*, schema::{grid_block_index_table, grid_block_index_table::dsl}, - ConnectionPool, }; use flowy_error::FlowyResult; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs index cf66211fab..06a5a2d68f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs @@ -5,7 +5,6 @@ use diesel::SqliteConnection; use flowy_database::{ prelude::*, schema::{kv_table, kv_table::dsl}, - ConnectionPool, }; use flowy_error::{FlowyError, FlowyResult}; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index ad0dcb1646..9c8a04bdc3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -1,16 +1,44 @@ use crate::services::field::*; -use bytes::Bytes; +use std::fmt::Formatter; + use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; pub trait CellDataOperation { - fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; - fn serialize_cell_data(&self, data: &str) -> Result; - // fn apply_changeset() + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result; } -#[derive(Serialize, Deserialize)] +#[derive(Debug)] +pub struct CellDataChangeset(String); + +impl std::fmt::Display for CellDataChangeset { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", &self.0) + } +} + +impl> std::convert::From for CellDataChangeset { + fn from(s: T) -> Self { + let s = s.as_ref().to_owned(); + CellDataChangeset(s) + } +} + +impl std::ops::Deref for CellDataChangeset { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Serialize, Deserialize)] pub struct TypeOptionCellData { pub data: String, pub field_type: FieldType, @@ -26,9 +54,9 @@ impl std::str::FromStr for TypeOptionCellData { } impl TypeOptionCellData { - pub fn new(data: &str, field_type: FieldType) -> Self { + pub fn new(data: T, field_type: FieldType) -> Self { TypeOptionCellData { - data: data.to_owned(), + data: data.to_string(), field_type, } } @@ -62,25 +90,34 @@ impl TypeOptionCellData { } } -pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result { +/// The function,apply_cell_data_changeset, will apply the cell_data_changeset. +/// +/// The cell_data_changeset will be deserialized into specific data base on the FieldType. +pub fn apply_cell_data_changeset>( + changeset: T, + cell_meta: Option, + field_meta: &FieldMeta, +) -> Result { match field_meta.field_type { - FieldType::RichText => RichTextTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::Number => NumberTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::DateTime => DateTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::Checkbox => CheckboxTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::Number => NumberTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::DateTime => DateTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), } } -pub fn deserialize_cell_data(data: String, field_meta: &FieldMeta) -> Result { +#[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)] +pub fn decode_cell_data(data: String, field_meta: &FieldMeta) -> Result { let s = match field_meta.field_type { - FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta), }; + tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str()); Ok(s) } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 698d4ac4ec..22fc0f14ae 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,5 +1,5 @@ -use crate::services::row::serialize_cell_data; -use bytes::Bytes; +use crate::services::row::apply_cell_data_changeset; + use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; @@ -36,7 +36,7 @@ impl<'a> CreateRowMetaBuilder<'a> { Err(FlowyError::internal().context(msg)) } Some(field_meta) => { - let data = serialize_cell_data(&data, field_meta)?; + let data = apply_cell_data_changeset(&data, None, field_meta)?; let cell = CellMeta::new(field_id, data); self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); Ok(()) diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index c497d7e12d..b37d937c0f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,4 +1,4 @@ -use crate::services::row::deserialize_cell_data; +use crate::services::row::decode_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, Row, RowMeta, RowOrder, @@ -47,7 +47,7 @@ pub fn make_cell_by_field_id( cell_meta: CellMeta, ) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; - match deserialize_cell_data(cell_meta.data, field_meta) { + match decode_cell_data(cell_meta.data, field_meta) { Ok(content) => { let cell = Cell::new(&field_id, content); Some((field_id, cell)) @@ -62,8 +62,8 @@ pub fn make_cell_by_field_id( #[allow(dead_code)] pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { let cell_meta = row_meta.cell_by_field_id.get(field_id)?.clone(); - match deserialize_cell_data(cell_meta.data, field_meta) { - Ok(content) => Some(Cell::new(&field_id, content)), + match decode_cell_data(cell_meta.data, field_meta) { + Ok(content) => Some(Cell::new(field_id, content)), Err(e) => { tracing::error!("{}", e); None diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 26dd3896dc..c14c937f00 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,7 +4,7 @@ use chrono::NaiveDateTime; use flowy_grid::services::field::{ MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, }; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataOperation, CreateRowMetaBuilder}; +use flowy_grid::services::row::{apply_cell_data_changeset, decode_cell_data, CellDataOperation, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, TypeOptionDataEntry, @@ -242,21 +242,21 @@ async fn grid_row_add_cells_test() { for field in &test.field_metas { match field.field_type { FieldType::RichText => { - let data = serialize_cell_data("hello world", field).unwrap(); + let data = apply_cell_data_changeset("hello world", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::Number => { - let data = serialize_cell_data("¥18,443", field).unwrap(); + let data = apply_cell_data_changeset("¥18,443", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::DateTime => { - let data = serialize_cell_data("1647251762", field).unwrap(); + let data = apply_cell_data_changeset("1647251762", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::SingleSelect => { let type_option = SingleSelectTypeOption::from(field); let options = type_option.options.first().unwrap(); - let data = type_option.serialize_cell_data(&options.id).unwrap(); + let data = type_option.apply_changeset(&options.id).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { @@ -267,11 +267,11 @@ async fn grid_row_add_cells_test() { .map(|option| option.id.clone()) .collect::>() .join(SELECTION_IDS_SEPARATOR); - let data = type_option.serialize_cell_data(&options).unwrap(); + let data = type_option.apply_changeset(&options).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::Checkbox => { - let data = serialize_cell_data("false", field).unwrap(); + let data = apply_cell_data_changeset("false", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } } @@ -357,7 +357,7 @@ async fn grid_row_add_date_cell_test() { let date_field = date_field.unwrap(); let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); assert_eq!( - deserialize_cell_data(cell_data.data.clone(), &date_field).unwrap(), + decode_cell_data(cell_data.data.clone(), &date_field).unwrap(), "2022/03/16 08:31", ); let scripts = vec![CreateRow { context }]; 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 c92a3b23a4..de15556008 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -64,12 +64,8 @@ pub struct FieldIdentifierPayload { pub grid_id: String, } -#[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldIdentifierParams { - #[pb(index = 1)] pub field_id: String, - - #[pb(index = 2)] pub grid_id: String, } @@ -92,12 +88,6 @@ pub struct FieldOrder { pub field_id: String, } -impl std::convert::Into> for FieldOrder { - fn into(self) -> Vec { - vec![self] - } -} - impl std::convert::From<&FieldMeta> for FieldOrder { fn from(field_meta: &FieldMeta) -> Self { Self { @@ -112,6 +102,12 @@ impl std::convert::From<&str> for FieldOrder { } } +impl std::convert::From for FieldOrder { + fn from(s: String) -> Self { + FieldOrder { field_id: s } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct GetEditFieldContextPayload { #[pb(index = 1)] @@ -211,6 +207,14 @@ impl std::convert::From> for RepeatedFieldOrder { } } +impl std::convert::From for RepeatedFieldOrder { + fn from(s: String) -> Self { + RepeatedFieldOrder { + items: vec![FieldOrder::from(s)], + } + } +} + #[derive(Debug, Default, Clone, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] @@ -327,6 +331,39 @@ impl Cell { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellIdentifierPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] + pub row_id: String, +} + +pub struct CellIdentifierParams { + pub grid_id: String, + pub field_id: String, + pub row_id: String, +} + +impl TryInto for CellIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + Ok(CellIdentifierParams { + grid_id: grid_id.0, + field_id: field_id.0, + row_id: row_id.0, + }) + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedCell { #[pb(index = 1)] @@ -430,7 +467,6 @@ pub struct CreateFieldPayload { pub start_field_id: Option, } -#[derive(Default, Clone)] pub struct CreateFieldParams { pub grid_id: String, pub field: Field, @@ -468,7 +504,6 @@ pub struct QueryFieldPayload { pub field_orders: RepeatedFieldOrder, } -#[derive(Default)] pub struct QueryFieldParams { pub grid_id: String, pub field_orders: RepeatedFieldOrder, @@ -495,7 +530,6 @@ pub struct QueryGridBlocksPayload { pub block_orders: Vec, } -#[derive(Default)] pub struct QueryGridBlocksParams { pub grid_id: String, pub block_orders: Vec, @@ -518,17 +552,12 @@ pub struct QueryRowPayload { #[pb(index = 1)] pub grid_id: String, - #[pb(index = 2)] - pub block_id: String, - #[pb(index = 3)] pub row_id: String, } -#[derive(Default)] pub struct QueryRowParams { pub grid_id: String, - pub block_id: String, pub row_id: String, } @@ -537,12 +566,10 @@ impl TryInto for QueryRowPayload { fn try_into(self) -> Result { let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let block_id = NotEmptyUuid::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; Ok(QueryRowParams { grid_id: grid_id.0, - block_id: block_id.0, row_id: row_id.0, }) } @@ -552,10 +579,14 @@ impl TryInto for QueryRowPayload { pub struct CreateSelectOptionPayload { #[pb(index = 1)] pub option_name: String, + + #[pb(index = 2)] + pub selected: bool, } pub struct CreateSelectOptionParams { pub option_name: String, + pub selected: bool, } impl TryInto for CreateSelectOptionPayload { @@ -565,6 +596,7 @@ impl TryInto for CreateSelectOptionPayload { let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; Ok(CreateSelectOptionParams { option_name: option_name.0, + selected: self.selected, }) } } 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 7d13585c86..e80c31d8ad 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 @@ -860,207 +860,6 @@ impl ::protobuf::reflect::ProtobufValue for FieldIdentifierPayload { } } -#[derive(PartialEq,Clone,Default)] -pub struct FieldIdentifierParams { - // message fields - pub field_id: ::std::string::String, - pub grid_id: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a FieldIdentifierParams { - fn default() -> &'a FieldIdentifierParams { - ::default_instance() - } -} - -impl FieldIdentifierParams { - pub fn new() -> FieldIdentifierParams { - ::std::default::Default::default() - } - - // string field_id = 1; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string 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()) - } -} - -impl ::protobuf::Message for FieldIdentifierParams { - 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 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.field_id); - } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_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.field_id.is_empty() { - os.write_string(1, &self.field_id)?; - } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_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() -> FieldIdentifierParams { - FieldIdentifierParams::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: &FieldIdentifierParams| { &m.field_id }, - |m: &mut FieldIdentifierParams| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &FieldIdentifierParams| { &m.grid_id }, - |m: &mut FieldIdentifierParams| { &mut m.grid_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "FieldIdentifierParams", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static FieldIdentifierParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(FieldIdentifierParams::new) - } -} - -impl ::protobuf::Clear for FieldIdentifierParams { - fn clear(&mut self) { - self.field_id.clear(); - self.grid_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for FieldIdentifierParams { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldIdentifierParams { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -3681,6 +3480,249 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } +#[derive(PartialEq,Clone,Default)] +pub struct CellIdentifierPayload { + // message fields + pub grid_id: ::std::string::String, + pub field_id: ::std::string::String, + pub row_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellIdentifierPayload { + fn default() -> &'a CellIdentifierPayload { + ::default_instance() + } +} + +impl CellIdentifierPayload { + pub fn new() -> CellIdentifierPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string row_id = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for CellIdentifierPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + 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() -> CellIdentifierPayload { + CellIdentifierPayload::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: &CellIdentifierPayload| { &m.grid_id }, + |m: &mut CellIdentifierPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellIdentifierPayload| { &m.field_id }, + |m: &mut CellIdentifierPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellIdentifierPayload| { &m.row_id }, + |m: &mut CellIdentifierPayload| { &mut m.row_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellIdentifierPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellIdentifierPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellIdentifierPayload::new) + } +} + +impl ::protobuf::Clear for CellIdentifierPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_id.clear(); + self.row_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellIdentifierPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedCell { // message fields @@ -5333,7 +5375,6 @@ impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { pub struct QueryRowPayload { // message fields pub grid_id: ::std::string::String, - pub block_id: ::std::string::String, pub row_id: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -5377,32 +5418,6 @@ impl QueryRowPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // string block_id = 2; - - - pub fn get_block_id(&self) -> &str { - &self.block_id - } - pub fn clear_block_id(&mut self) { - self.block_id.clear(); - } - - // Param is passed by value, moved - pub fn set_block_id(&mut self, v: ::std::string::String) { - self.block_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_id(&mut self) -> &mut ::std::string::String { - &mut self.block_id - } - - // Take field - pub fn take_block_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) - } - // string row_id = 3; @@ -5442,9 +5457,6 @@ impl ::protobuf::Message for QueryRowPayload { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; - }, 3 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, @@ -5463,9 +5475,6 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if !self.block_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.block_id); - } if !self.row_id.is_empty() { my_size += ::protobuf::rt::string_size(3, &self.row_id); } @@ -5478,9 +5487,6 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if !self.block_id.is_empty() { - os.write_string(2, &self.block_id)?; - } if !self.row_id.is_empty() { os.write_string(3, &self.row_id)?; } @@ -5527,11 +5533,6 @@ impl ::protobuf::Message for QueryRowPayload { |m: &QueryRowPayload| { &m.grid_id }, |m: &mut QueryRowPayload| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "block_id", - |m: &QueryRowPayload| { &m.block_id }, - |m: &mut QueryRowPayload| { &mut m.block_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", |m: &QueryRowPayload| { &m.row_id }, @@ -5554,7 +5555,6 @@ impl ::protobuf::Message for QueryRowPayload { impl ::protobuf::Clear for QueryRowPayload { fn clear(&mut self) { self.grid_id.clear(); - self.block_id.clear(); self.row_id.clear(); self.unknown_fields.clear(); } @@ -5576,6 +5576,7 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { pub struct CreateSelectOptionPayload { // message fields pub option_name: ::std::string::String, + pub selected: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -5617,6 +5618,21 @@ impl CreateSelectOptionPayload { pub fn take_option_name(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.option_name, ::std::string::String::new()) } + + // bool selected = 2; + + + pub fn get_selected(&self) -> bool { + self.selected + } + pub fn clear_selected(&mut self) { + self.selected = false; + } + + // Param is passed by value, moved + pub fn set_selected(&mut self, v: bool) { + self.selected = v; + } } impl ::protobuf::Message for CreateSelectOptionPayload { @@ -5631,6 +5647,13 @@ impl ::protobuf::Message for CreateSelectOptionPayload { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.option_name)?; }, + 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.selected = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -5646,6 +5669,9 @@ impl ::protobuf::Message for CreateSelectOptionPayload { if !self.option_name.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.option_name); } + if self.selected != false { + my_size += 2; + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -5655,6 +5681,9 @@ impl ::protobuf::Message for CreateSelectOptionPayload { if !self.option_name.is_empty() { os.write_string(1, &self.option_name)?; } + if self.selected != false { + os.write_bool(2, self.selected)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -5698,6 +5727,11 @@ impl ::protobuf::Message for CreateSelectOptionPayload { |m: &CreateSelectOptionPayload| { &m.option_name }, |m: &mut CreateSelectOptionPayload| { &mut m.option_name }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "selected", + |m: &CreateSelectOptionPayload| { &m.selected }, + |m: &mut CreateSelectOptionPayload| { &mut m.selected }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateSelectOptionPayload", fields, @@ -5715,6 +5749,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { impl ::protobuf::Clear for CreateSelectOptionPayload { fn clear(&mut self) { self.option_name.clear(); + self.selected = false; self.unknown_fields.clear(); } } @@ -5742,55 +5777,55 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"L\n\x16FieldIdentifi\ erPayload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\ - \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"K\n\x15FieldIdentifierParams\ - \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ - id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldContextPayloa\ - d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_\ - id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\ - \x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\n\x10EditFiel\ - dPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\ - \x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_type\x18\x03\ - \x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\x02\ - \x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\x03\ - \x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05items\ - \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ - RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ - lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ - yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ - \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ - (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ - \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ - \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ - \x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\ - \x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ - 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ - \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ - \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ - R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ - lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ - \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ - idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ - \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ - rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ - \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ - \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ - \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ - ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ - ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ - \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ - ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ - \x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ - \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"<\n\x19CreateSelec\ - tOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionNameb\ - \x06proto3\ + \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08\ + field_id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldConte\ + xtPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\ + \x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\ + \x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\ + \n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridI\ + d\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_typ\ + e\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\ + \x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\ + \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFiel\ + dOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\ + \n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\ + \n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\ + \x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ + Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ + lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ + \x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05item\ + s\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\ + \x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\ + \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\ + \x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\ + \x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07\ + content\"b\n\x15CellIdentifierPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ + \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"+\n\x0cRepeatedCell\ + \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11Cre\ + ateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06\ + GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlock\ + Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayl\ + oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_\ + row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\ + \"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ + \tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05fie\ + ld\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\ + \x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\ + \x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\ + \x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\ + \x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayl\ + oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_o\ + rders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrders\"A\n\x0fQ\ + ueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"X\n\x19CreateSelectOption\ + Payload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionName\x12\x1a\ + \n\x08selected\x18\x02\x20\x01(\x08R\x08selectedb\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 6e4a4f31cf..b3fcea8740 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 @@ -19,10 +19,6 @@ message FieldIdentifierPayload { string field_id = 1; string grid_id = 2; } -message FieldIdentifierParams { - string field_id = 1; - string grid_id = 2; -} message FieldOrder { string field_id = 1; } @@ -74,6 +70,11 @@ message Cell { string field_id = 1; string content = 2; } +message CellIdentifierPayload { + string grid_id = 1; + string field_id = 2; + string row_id = 3; +} message RepeatedCell { repeated Cell items = 1; } @@ -106,9 +107,9 @@ message QueryGridBlocksPayload { } message QueryRowPayload { string grid_id = 1; - string block_id = 2; string row_id = 3; } message CreateSelectOptionPayload { string option_name = 1; + bool selected = 2; } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index f022488f0a..2d2e9888f6 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -4,7 +4,6 @@ use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta, - RepeatedFieldOrder, }; use lib_infra::uuid; From c7a3bb73b98785c2c34eba565ded2c7c335c4ce9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 5 Apr 2022 22:46:23 +0800 Subject: [PATCH 098/179] chore: listen on row update --- .../application/grid/grid_block_service.dart | 2 +- .../application/grid/row/row_bloc.dart | 61 +++++++++-------- .../application/grid/row/row_listener.dart | 9 +-- .../flowy-grid/dart_notification.pbenum.dart | 6 +- .../flowy-grid/dart_notification.pbjson.dart | 6 +- .../flowy-grid/src/dart_notification.rs | 4 +- .../src/protobuf/model/dart_notification.rs | 18 ++--- .../protobuf/proto/dart_notification.proto | 4 +- .../src/services/block_meta_editor.rs | 67 ++++++++++++------- 9 files changed, 94 insertions(+), 83 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 668b523c74..1dcd9685d1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -80,7 +80,7 @@ class GridBlockListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.DidUpdateRow: + case GridNotification.DidUpdateBlock: result.fold( (payload) => blockUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]), (error) => blockUpdateNotifier.value = right(error), diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 14f30b4359..8592f4b1c3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -36,28 +36,42 @@ class RowBloc extends Bloc { initial: (_InitialRow value) async { _startListening(); await _loadRow(emit); - add(const RowEvent.didUpdateCell()); }, createRow: (_CreateRow value) { rowService.createRow(); }, - didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - emit(state.copyWith(fields: value.fields)); - add(const RowEvent.didUpdateCell()); + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) async { + await _handleFieldUpdate(emit, value); }, - didUpdateCell: (_DidUpdateCell value) async { - final optionRow = await state.row; - final CellDataMap cellDataMap = optionRow.fold( - () => CellDataMap.identity(), - (row) => _makeCellDatas(row), - ); - emit(state.copyWith(cellDataMap: Some(cellDataMap))); + didUpdateRow: (_DidUpdateRow value) async { + _handleRowUpdate(value, emit); }, ); }, ); } + void _handleRowUpdate(_DidUpdateRow value, Emitter emit) { + final CellDataMap cellDataMap = _makeCellDatas(value.row); + emit(state.copyWith( + row: Future(() => Some(value.row)), + cellDataMap: Some(cellDataMap), + )); + } + + Future _handleFieldUpdate(Emitter emit, _DidReceiveFieldUpdate value) async { + final optionRow = await state.row; + final CellDataMap cellDataMap = optionRow.fold( + () => CellDataMap.identity(), + (row) => _makeCellDatas(row), + ); + + emit(state.copyWith( + fields: value.fields, + cellDataMap: Some(cellDataMap), + )); + } + @override Future close() async { await rowlistener.stop(); @@ -68,18 +82,7 @@ class RowBloc extends Bloc { Future _startListening() async { rowlistener.updateRowNotifier.addPublishListener((result) { result.fold( - (row) { - // - }, - (err) => Log.error(err), - ); - }); - - rowlistener.updateCellNotifier.addPublishListener((result) { - result.fold( - (repeatedCell) { - Log.info("$repeatedCell"); - }, + (row) => add(RowEvent.didUpdateRow(row)), (err) => Log.error(err), ); }); @@ -96,16 +99,12 @@ class RowBloc extends Bloc { } Future _loadRow(Emitter emit) async { - final Future> row = rowService.getRow().then((result) { + rowService.getRow().then((result) { return result.fold( - (row) => Some(row), - (err) { - Log.error(err); - return none(); - }, + (row) => add(RowEvent.didUpdateRow(row)), + (err) => Log.error(err), ); }); - emit(state.copyWith(row: row)); } CellDataMap _makeCellDatas(Row row) { @@ -130,7 +129,7 @@ class RowEvent with _$RowEvent { const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; - const factory RowEvent.didUpdateCell() = _DidUpdateCell; + const factory RowEvent.didUpdateRow(Row row) = _DidUpdateRow; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart index 011dbd8636..12efb78a1b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart @@ -9,13 +9,11 @@ import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; import 'package:dartz/dartz.dart'; -typedef UpdateCellNotifiedValue = Either; typedef UpdateRowNotifiedValue = Either; typedef UpdateFieldNotifiedValue = Either, FlowyError>; class RowListener { final String rowId; - PublishNotifier updateCellNotifier = PublishNotifier(); PublishNotifier updateRowNotifier = PublishNotifier(); StreamSubscription? _subscription; GridNotificationParser? _parser; @@ -35,10 +33,10 @@ class RowListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.GridDidUpdateCells: + case GridNotification.DidUpdateRow: result.fold( - (payload) => updateCellNotifier.value = left(RepeatedCell.fromBuffer(payload)), - (error) => updateCellNotifier.value = right(error), + (payload) => updateRowNotifier.value = left(Row.fromBuffer(payload)), + (error) => updateRowNotifier.value = right(error), ); break; default: @@ -49,7 +47,6 @@ class RowListener { Future stop() async { _parser = null; await _subscription?.cancel(); - updateCellNotifier.dispose(); updateRowNotifier.dispose(); } } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 634de1b7f2..bf1367e43f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -12,16 +12,16 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock'); - static const GridNotification DidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); - static const GridNotification GridDidUpdateCells = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); + static const GridNotification DidUpdateBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateBlock'); + static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields'); static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); static const $core.List values = [ Unknown, DidCreateBlock, + DidUpdateBlock, DidUpdateRow, - GridDidUpdateCells, DidUpdateFields, DidUpdateField, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 571fe64399..92639052c0 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -14,12 +14,12 @@ const GridNotification$json = const { '2': const [ const {'1': 'Unknown', '2': 0}, const {'1': 'DidCreateBlock', '2': 11}, - const {'1': 'DidUpdateRow', '2': 20}, - const {'1': 'GridDidUpdateCells', '2': 30}, + const {'1': 'DidUpdateBlock', '2': 20}, + const {'1': 'DidUpdateRow', '2': 30}, const {'1': 'DidUpdateFields', '2': 40}, const {'1': 'DidUpdateField', '2': 41}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhAKDERpZFVwZGF0ZVJvdxAUEhYKEkdyaWREaWRVcGRhdGVDZWxscxAeEhMKD0RpZFVwZGF0ZUZpZWxkcxAoEhIKDkRpZFVwZGF0ZUZpZWxkECk='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEwoPRGlkVXBkYXRlRmllbGRzECgSEgoORGlkVXBkYXRlRmllbGQQKQ=='); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 364c42f680..2a8ffea466 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -6,8 +6,8 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; pub enum GridNotification { Unknown = 0, DidCreateBlock = 11, - DidUpdateRow = 20, - GridDidUpdateCells = 30, + DidUpdateBlock = 20, + DidUpdateRow = 30, DidUpdateFields = 40, DidUpdateField = 41, } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 32e697b36e..2c118b9c1e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -27,8 +27,8 @@ pub enum GridNotification { Unknown = 0, DidCreateBlock = 11, - DidUpdateRow = 20, - GridDidUpdateCells = 30, + DidUpdateBlock = 20, + DidUpdateRow = 30, DidUpdateFields = 40, DidUpdateField = 41, } @@ -42,8 +42,8 @@ impl ::protobuf::ProtobufEnum for GridNotification { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), 11 => ::std::option::Option::Some(GridNotification::DidCreateBlock), - 20 => ::std::option::Option::Some(GridNotification::DidUpdateRow), - 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), + 20 => ::std::option::Option::Some(GridNotification::DidUpdateBlock), + 30 => ::std::option::Option::Some(GridNotification::DidUpdateRow), 40 => ::std::option::Option::Some(GridNotification::DidUpdateFields), 41 => ::std::option::Option::Some(GridNotification::DidUpdateField), _ => ::std::option::Option::None @@ -54,8 +54,8 @@ impl ::protobuf::ProtobufEnum for GridNotification { static values: &'static [GridNotification] = &[ GridNotification::Unknown, GridNotification::DidCreateBlock, + GridNotification::DidUpdateBlock, GridNotification::DidUpdateRow, - GridNotification::GridDidUpdateCells, GridNotification::DidUpdateFields, GridNotification::DidUpdateField, ]; @@ -86,10 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x86\x01\n\x10GridNotification\x12\x0b\n\ - \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUp\ - dateRow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDid\ - UpdateFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\ + \n\x17dart_notification.proto*\x82\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x12\n\x0eDidUp\ + dateBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x13\n\x0fDidUpda\ + teFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 176e0d83a4..62230e6376 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -3,8 +3,8 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; DidCreateBlock = 11; - DidUpdateRow = 20; - GridDidUpdateCells = 30; + DidUpdateBlock = 20; + DidUpdateRow = 30; DidUpdateFields = 40; DidUpdateField = 41; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index abdf1d5cbe..9a8ecd4655 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,12 +1,12 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::persistence::block_index::BlockIndexPersistence; -use crate::services::row::{make_block_row_ids, make_cell_by_field_id, GridBlockSnapshot}; +use crate::services::row::{make_block_row_ids, make_cell_by_field_id, make_rows_from_row_metas, GridBlockSnapshot}; use bytes::Bytes; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMeta, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta, + CellMeta, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, Row, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -120,9 +120,10 @@ impl GridBlockMetaEditorManager { } pub async fn update_row_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { - let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let row_id = changeset.row_id.clone(); + let editor = self.get_editor_from_row_id(&row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - self.notify_did_update_cells(changeset, field_metas)?; + self.notify_did_update_row(&row_id, field_metas).await?; Ok(()) } @@ -171,35 +172,49 @@ impl GridBlockMetaEditorManager { async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { let block_order: GridBlockOrder = block_id.into(); - send_dart_notification(&self.grid_id, GridNotification::DidUpdateRow) + send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock) .payload(block_order) .send(); Ok(()) } - fn notify_did_update_cells(&self, changeset: RowMetaChangeset, field_metas: &[FieldMeta]) -> FlowyResult<()> { - let field_meta_map = field_metas - .iter() - .map(|field_meta| (&field_meta.id, field_meta)) - .collect::>(); - - let mut cells = vec![]; - changeset - .cell_by_field_id - .into_iter() - .for_each( - |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) { - None => {} - Some((_, cell)) => cells.push(cell), - }, - ); - - if !cells.is_empty() { - send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateCells) - .payload(RepeatedCell::from(cells)) - .send(); + async fn notify_did_update_row(&self, row_id: &str, field_metas: &[FieldMeta]) -> FlowyResult<()> { + match self.get_row_meta(row_id).await? { + None => {} + Some(row_meta) => { + let row_metas = vec![row_meta]; + if let Some(row) = make_rows_from_row_metas(&field_metas, &row_metas).pop() { + send_dart_notification(row_id, GridNotification::DidUpdateRow) + .payload(row) + .send(); + } + } } Ok(()) + + // + // let field_meta_map = field_metas + // .iter() + // .map(|field_meta| (&field_meta.id, field_meta)) + // .collect::>(); + // + // let mut cells = vec![]; + // changeset + // .cell_by_field_id + // .into_iter() + // .for_each( + // |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) { + // None => {} + // Some((_, cell)) => cells.push(cell), + // }, + // ); + // + // if !cells.is_empty() { + // send_dart_notification(&changeset.row_id, GridNotification::DidUpdateRow) + // .payload(RepeatedCell::from(cells)) + // .send(); + // } + // Ok(()) } } From 6a36e2bcfdc914f9e2b8793248eb53f1a437f103 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 6 Apr 2022 10:32:08 +0800 Subject: [PATCH 099/179] chore: listen on cell update --- .../lib/core/notification_helper.dart | 19 + .../grid/cell_bloc/cell_listener.dart | 40 ++ .../grid/cell_bloc/selection_cell_bloc.dart | 17 +- .../grid/field/field_listener.dart | 23 +- .../application/grid/field/grid_listenr.dart | 20 +- .../application/grid/grid_block_service.dart | 20 +- .../application/grid/row/row_bloc.dart | 1 - .../application/grid/row/row_listener.dart | 19 +- .../application/grid/row/row_service.dart | 2 - .../grid/src/widgets/row/grid_row.dart | 26 +- .../flowy-grid-data-model/grid.pb.dart | 102 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 16 + .../flowy-grid/dart_notification.pbenum.dart | 2 + .../flowy-grid/dart_notification.pbjson.dart | 3 +- frontend/rust-lib/dart-ffi/Cargo.toml | 2 +- .../flowy-grid/src/dart_notification.rs | 1 + .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- .../src/protobuf/model/dart_notification.rs | 10 +- .../protobuf/proto/dart_notification.proto | 1 + .../src/services/block_meta_editor.rs | 26 +- .../flowy-grid/src/services/grid_editor.rs | 7 +- .../src/entities/grid.rs | 23 +- .../src/protobuf/model/grid.rs | 369 +++++++++++++++++- .../src/protobuf/proto/grid.proto | 6 + 24 files changed, 640 insertions(+), 117 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart diff --git a/frontend/app_flowy/lib/core/notification_helper.dart b/frontend/app_flowy/lib/core/notification_helper.dart index d815bf92bb..650abc544c 100644 --- a/frontend/app_flowy/lib/core/notification_helper.dart +++ b/frontend/app_flowy/lib/core/notification_helper.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:typed_data'; import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart'; @@ -5,6 +6,7 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; // User typedef UserNotificationCallback = void Function(UserNotification, Either); @@ -45,6 +47,23 @@ class GridNotificationParser extends NotificationParser result); + +class GridNotificationListener { + StreamSubscription? _subscription; + GridNotificationParser? _parser; + + GridNotificationListener({required String objectId, required GridNotificationHandler handler}) + : _parser = GridNotificationParser(id: objectId, callback: handler) { + _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); + } + + Future stop() async { + _parser = null; + await _subscription?.cancel(); + } +} + class NotificationParser { String? id; void Function(T, Either) callback; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart new file mode 100644 index 0000000000..d1fb0acc0c --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart @@ -0,0 +1,40 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; + +typedef UpdateFieldNotifiedValue = Either; + +class CellListener { + final String rowId; + final String fieldId; + PublishNotifier updateCellNotifier = PublishNotifier(); + GridNotificationListener? _listener; + CellListener({required this.rowId, required this.fieldId}); + + void start() { + _listener = GridNotificationListener(objectId: "$rowId:$fieldId", handler: _handler); + } + + void _handler(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.DidUpdateCell: + result.fold( + (payload) => updateCellNotifier.value = left(CellNotificationData.fromBuffer(payload)), + (error) => updateCellNotifier.value = right(error), + ); + break; + default: + break; + } + } + + Future stop() async { + await _listener?.stop(); + updateCellNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 1b38376e86..48c11622fe 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,7 +1,6 @@ -import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -12,17 +11,20 @@ part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { final CellService _service; + final CellListener _listener; SelectionCellBloc({ required CellService service, required CellData cellData, }) : _service = service, + _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(SelectionCellState.initial(cellData)) { on( (event, emit) async { await event.map( initial: (_InitialCell value) async { _loadOptions(); + _startListening(); }, didReceiveOptions: (_DidReceiveOptions value) { emit(state.copyWith(options: value.options, selectedOptions: value.selectedOptions)); @@ -34,6 +36,7 @@ class SelectionCellBloc extends Bloc { @override Future close() async { + await _listener.stop(); return super.close(); } @@ -52,6 +55,16 @@ class SelectionCellBloc extends Bloc { (err) => Log.error(err), ); } + + void _startListening() { + _listener.updateCellNotifier.addPublishListener((result) { + result.fold( + (notificationData) => _loadOptions(), + (err) => Log.error(err), + ); + }); + _listener.start(); + } } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart index eda5d83e69..ed09ca9b82 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart @@ -1,9 +1,7 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; -import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; @@ -14,23 +12,21 @@ typedef UpdateFieldNotifiedValue = Either; class FieldListener { final String fieldId; PublishNotifier updateFieldNotifier = PublishNotifier(); - StreamSubscription? _subscription; - GridNotificationParser? _parser; + GridNotificationListener? _listener; FieldListener({required this.fieldId}); void start() { - _parser = GridNotificationParser( - id: fieldId, - callback: (ty, result) { - _handleObservableType(ty, result); - }, + _listener = GridNotificationListener( + objectId: fieldId, + handler: _handler, ); - - _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } - void _handleObservableType(GridNotification ty, Either result) { + void _handler( + GridNotification ty, + Either result, + ) { switch (ty) { case GridNotification.DidUpdateField: result.fold( @@ -44,8 +40,7 @@ class FieldListener { } Future stop() async { - _parser = null; - await _subscription?.cancel(); + await _listener?.stop(); updateFieldNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index 60ff7dd415..fa92d84b79 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -1,9 +1,7 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; -import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; @@ -14,22 +12,17 @@ typedef UpdateFieldNotifiedValue = Either, FlowyError>; class GridFieldsListener { final String gridId; PublishNotifier updateFieldsNotifier = PublishNotifier(); - StreamSubscription? _subscription; - GridNotificationParser? _parser; + GridNotificationListener? _listener; GridFieldsListener({required this.gridId}); void start() { - _parser = GridNotificationParser( - id: gridId, - callback: (ty, result) { - _handleObservableType(ty, result); - }, + _listener = GridNotificationListener( + objectId: gridId, + handler: _handler, ); - - _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } - void _handleObservableType(GridNotification ty, Either result) { + void _handler(GridNotification ty, Either result) { switch (ty) { case GridNotification.DidUpdateFields: result.fold( @@ -43,8 +36,7 @@ class GridFieldsListener { } Future stop() async { - _parser = null; - await _subscription?.cancel(); + await _listener?.stop(); updateFieldsNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 1dcd9685d1..e6ecad0949 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -3,10 +3,8 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; -import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; @@ -62,23 +60,18 @@ class GridBlockService { class GridBlockListener { final String gridId; PublishNotifier, FlowyError>> blockUpdateNotifier = PublishNotifier(comparable: null); - StreamSubscription? _subscription; - GridNotificationParser? _parser; + GridNotificationListener? _listener; GridBlockListener({required this.gridId}); void start() { - _parser = GridNotificationParser( - id: gridId, - callback: (ty, result) { - _handleObservableType(ty, result); - }, + _listener = GridNotificationListener( + objectId: gridId, + handler: _handler, ); - - _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } - void _handleObservableType(GridNotification ty, Either result) { + void _handler(GridNotification ty, Either result) { switch (ty) { case GridNotification.DidUpdateBlock: result.fold( @@ -93,8 +86,7 @@ class GridBlockListener { } Future stop() async { - _parser = null; - await _subscription?.cancel(); + await _listener?.stop(); blockUpdateNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 8592f4b1c3..3c29d82d46 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -114,7 +114,6 @@ class RowBloc extends Bloc { map[field.id] = CellData( rowId: row.id, gridId: rowService.gridId, - blockId: rowService.blockId, cell: row.cellByFieldId[field.id], field: field, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart index 12efb78a1b..716d252802 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart @@ -1,8 +1,6 @@ -import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; -import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; @@ -15,23 +13,15 @@ typedef UpdateFieldNotifiedValue = Either, FlowyError>; class RowListener { final String rowId; PublishNotifier updateRowNotifier = PublishNotifier(); - StreamSubscription? _subscription; - GridNotificationParser? _parser; + GridNotificationListener? _listener; RowListener({required this.rowId}); void start() { - _parser = GridNotificationParser( - id: rowId, - callback: (ty, result) { - _handleObservableType(ty, result); - }, - ); - - _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); + _listener = GridNotificationListener(objectId: rowId, handler: _handler); } - void _handleObservableType(GridNotification ty, Either result) { + void _handler(GridNotification ty, Either result) { switch (ty) { case GridNotification.DidUpdateRow: result.fold( @@ -45,8 +35,7 @@ class RowListener { } Future stop() async { - _parser = null; - await _subscription?.cancel(); + await _listener?.stop(); updateRowNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 1b3f9e87ec..8875f9dc98 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -31,14 +31,12 @@ class RowService { class CellData extends Equatable { final String gridId; final String rowId; - final String blockId; final Field field; final Cell? cell; const CellData({ required this.rowId, required this.gridId, - required this.blockId, required this.field, required this.cell, }); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 5586328e32..d3ac6d8ce3 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -122,24 +122,22 @@ class _RowCells extends StatelessWidget { return BlocBuilder( buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { - final List children = state.cellDataMap.fold( - () => [], - (dataMap) { - return dataMap.values.map( - (value) { - return CellContainer( - width: value.field.width.toDouble(), - child: buildGridCell(value), - ); - }, - ).toList(); - }, - ); - + final List children = state.cellDataMap.fold(() => [], _toCells); return Row(children: children); }, ); } + + List _toCells(CellDataMap dataMap) { + return dataMap.values.map( + (cellData) { + return CellContainer( + width: cellData.field.width.toDouble(), + child: buildGridCell(cellData), + ); + }, + ).toList(); + } } class RowRegionStateNotifier extends ChangeNotifier { 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 ab195308c6..2cd87115bf 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 @@ -1099,6 +1099,108 @@ class CellIdentifierPayload extends $pb.GeneratedMessage { void clearRowId() => clearField(3); } +enum CellNotificationData_OneOfContent { + content, + notSet +} + +class CellNotificationData extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CellNotificationData_OneOfContent> _CellNotificationData_OneOfContentByTag = { + 4 : CellNotificationData_OneOfContent.content, + 0 : CellNotificationData_OneOfContent.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellNotificationData', createEmptyInstance: create) + ..oo(0, [4]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') + ..hasRequiredFields = false + ; + + CellNotificationData._() : super(); + factory CellNotificationData({ + $core.String? gridId, + $core.String? fieldId, + $core.String? rowId, + $core.String? content, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (rowId != null) { + _result.rowId = rowId; + } + if (content != null) { + _result.content = content; + } + return _result; + } + factory CellNotificationData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellNotificationData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CellNotificationData clone() => CellNotificationData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellNotificationData copyWith(void Function(CellNotificationData) updates) => super.copyWith((message) => updates(message as CellNotificationData)) as CellNotificationData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellNotificationData create() => CellNotificationData._(); + CellNotificationData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellNotificationData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellNotificationData? _defaultInstance; + + CellNotificationData_OneOfContent whichOneOfContent() => _CellNotificationData_OneOfContentByTag[$_whichOneof(0)]!; + void clearOneOfContent() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get fieldId => $_getSZ(1); + @$pb.TagNumber(2) + set fieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get rowId => $_getSZ(2); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(2); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); + + @$pb.TagNumber(4) + $core.String get content => $_getSZ(3); + @$pb.TagNumber(4) + set content($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasContent() => $_has(3); + @$pb.TagNumber(4) + void clearContent() => clearField(4); +} + class RepeatedCell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedCell', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Cell.create) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index c51a224a9e..cf58ec74a2 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 @@ -215,6 +215,22 @@ const CellIdentifierPayload$json = const { /// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); +@$core.Deprecated('Use cellNotificationDataDescriptor instead') +const CellNotificationData$json = const { + '1': 'CellNotificationData', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'content', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'content'}, + ], + '8': const [ + const {'1': 'one_of_content'}, + ], +}; + +/// Descriptor for `CellNotificationData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellNotificationDataDescriptor = $convert.base64Decode('ChRDZWxsTm90aWZpY2F0aW9uRGF0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSGQoIZmllbGRfaWQYAiABKAlSB2ZpZWxkSWQSFQoGcm93X2lkGAMgASgJUgVyb3dJZBIaCgdjb250ZW50GAQgASgJSABSB2NvbnRlbnRCEAoOb25lX29mX2NvbnRlbnQ='); @$core.Deprecated('Use repeatedCellDescriptor instead') const RepeatedCell$json = const { '1': 'RepeatedCell', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index bf1367e43f..8f1cd90c29 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -14,6 +14,7 @@ class GridNotification extends $pb.ProtobufEnum { static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock'); static const GridNotification DidUpdateBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateBlock'); static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); + static const GridNotification DidUpdateCell = GridNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateCell'); static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields'); static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); @@ -22,6 +23,7 @@ class GridNotification extends $pb.ProtobufEnum { DidCreateBlock, DidUpdateBlock, DidUpdateRow, + DidUpdateCell, DidUpdateFields, DidUpdateField, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 92639052c0..504d7e56f5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -16,10 +16,11 @@ const GridNotification$json = const { const {'1': 'DidCreateBlock', '2': 11}, const {'1': 'DidUpdateBlock', '2': 20}, const {'1': 'DidUpdateRow', '2': 30}, + const {'1': 'DidUpdateCell', '2': 31}, const {'1': 'DidUpdateFields', '2': 40}, const {'1': 'DidUpdateField', '2': 41}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEwoPRGlkVXBkYXRlRmllbGRzECgSEgoORGlkVXBkYXRlRmllbGQQKQ=='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEQoNRGlkVXBkYXRlQ2VsbBAfEhMKD0RpZFVwZGF0ZUZpZWxkcxAoEhIKDkRpZFVwZGF0ZUZpZWxkECk='); diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index df26694331..143dc76b1e 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" name = "dart_ffi" # this value will change depending on the target os # default static lib -crate-type = ["staticlib"] +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 2a8ffea466..914b3088f5 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -8,6 +8,7 @@ pub enum GridNotification { DidCreateBlock = 11, DidUpdateBlock = 20, DidUpdateRow = 30, + DidUpdateCell = 31, DidUpdateFields = 40, DidUpdateField = 41, } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 62cbb4abec..2a8bb86103 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -132,7 +132,7 @@ pub(crate) async fn get_select_option_handler( data: Data, manager: AppData>, ) -> DataResult { - let params: CellIdentifierParams = data.into_inner().try_into()?; + let params: CellIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; match editor .get_field_metas(Some(vec![params.field_id.as_str()])) diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 2c118b9c1e..e02f234e9f 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -29,6 +29,7 @@ pub enum GridNotification { DidCreateBlock = 11, DidUpdateBlock = 20, DidUpdateRow = 30, + DidUpdateCell = 31, DidUpdateFields = 40, DidUpdateField = 41, } @@ -44,6 +45,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { 11 => ::std::option::Option::Some(GridNotification::DidCreateBlock), 20 => ::std::option::Option::Some(GridNotification::DidUpdateBlock), 30 => ::std::option::Option::Some(GridNotification::DidUpdateRow), + 31 => ::std::option::Option::Some(GridNotification::DidUpdateCell), 40 => ::std::option::Option::Some(GridNotification::DidUpdateFields), 41 => ::std::option::Option::Some(GridNotification::DidUpdateField), _ => ::std::option::Option::None @@ -56,6 +58,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { GridNotification::DidCreateBlock, GridNotification::DidUpdateBlock, GridNotification::DidUpdateRow, + GridNotification::DidUpdateCell, GridNotification::DidUpdateFields, GridNotification::DidUpdateField, ]; @@ -86,10 +89,11 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x82\x01\n\x10GridNotification\x12\x0b\n\ + \n\x17dart_notification.proto*\x95\x01\n\x10GridNotification\x12\x0b\n\ \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x12\n\x0eDidUp\ - dateBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x13\n\x0fDidUpda\ - teFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\ + dateBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUpdate\ + Cell\x10\x1f\x12\x13\n\x0fDidUpdateFields\x10(\x12\x12\n\x0eDidUpdateFie\ + ld\x10)b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 62230e6376..6ecb36847a 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -5,6 +5,7 @@ enum GridNotification { DidCreateBlock = 11; DidUpdateBlock = 20; DidUpdateRow = 30; + DidUpdateCell = 31; DidUpdateFields = 40; DidUpdateField = 41; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 9a8ecd4655..d8231dbb2e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -6,8 +6,8 @@ use bytes::Bytes; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMeta, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, Row, RowMeta, - RowMetaChangeset, RowOrder, + CellIdentifier, CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, + GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, Row, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{ @@ -119,11 +119,19 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub async fn update_row_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { let row_id = changeset.row_id.clone(); let editor = self.get_editor_from_row_id(&row_id).await?; - let _ = editor.update_row(changeset.clone()).await?; - self.notify_did_update_row(&row_id, field_metas).await?; + let row_changeset: RowMetaChangeset = changeset.clone().into(); + let _ = editor.update_row(row_changeset).await?; + + let cell_notification_data = CellNotificationData { + grid_id: changeset.grid_id, + field_id: changeset.field_id, + row_id: changeset.row_id, + content: changeset.data, + }; + self.notify_did_update_cell(cell_notification_data).await?; Ok(()) } @@ -178,6 +186,14 @@ impl GridBlockMetaEditorManager { Ok(()) } + async fn notify_did_update_cell(&self, data: CellNotificationData) -> FlowyResult<()> { + let id = format!("{}:{}", data.row_id, data.field_id); + send_dart_notification(&id, GridNotification::DidUpdateCell) + .payload(data) + .send(); + Ok(()) + } + async fn notify_did_update_row(&self, row_id: &str, field_metas: &[FieldMeta]) -> FlowyResult<()> { match self.get_row_meta(row_id).await? { None => {} 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 17fb852e07..1a184d51e9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -278,12 +278,7 @@ impl ClientGridEditor { Some(field_meta) => { // Update the changeset.data property with the return value. changeset.data = Some(apply_cell_data_changeset(cell_data_changeset, cell_meta, field_meta)?); - let field_metas = self.get_field_metas::(None).await?; - let row_changeset: RowMetaChangeset = changeset.into(); - let _ = self - .block_meta_manager - .update_row_cells(&field_metas, row_changeset) - .await?; + let _ = self.block_meta_manager.update_cell(changeset).await?; 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 de15556008..56c76d1925 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -343,20 +343,20 @@ pub struct CellIdentifierPayload { pub row_id: String, } -pub struct CellIdentifierParams { +pub struct CellIdentifier { pub grid_id: String, pub field_id: String, pub row_id: String, } -impl TryInto for CellIdentifierPayload { +impl TryInto for CellIdentifierPayload { type Error = ErrorCode; - fn try_into(self) -> Result { + fn try_into(self) -> Result { let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; - Ok(CellIdentifierParams { + Ok(CellIdentifier { grid_id: grid_id.0, field_id: field_id.0, row_id: row_id.0, @@ -364,6 +364,21 @@ impl TryInto for CellIdentifierPayload { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellNotificationData { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] + pub row_id: String, + + #[pb(index = 4, one_of)] + pub content: Option, +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedCell { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index e80c31d8ad..a64dad9191 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 @@ -3723,6 +3723,331 @@ impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct CellNotificationData { + // message fields + pub grid_id: ::std::string::String, + pub field_id: ::std::string::String, + pub row_id: ::std::string::String, + // message oneof groups + pub one_of_content: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellNotificationData { + fn default() -> &'a CellNotificationData { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CellNotificationData_oneof_one_of_content { + content(::std::string::String), +} + +impl CellNotificationData { + pub fn new() -> CellNotificationData { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string row_id = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // string content = 4; + + + pub fn get_content(&self) -> &str { + match self.one_of_content { + ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(ref v)) => v, + _ => "", + } + } + pub fn clear_content(&mut self) { + self.one_of_content = ::std::option::Option::None; + } + + pub fn has_content(&self) -> bool { + match self.one_of_content { + ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_content(&mut self, v: ::std::string::String) { + self.one_of_content = ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(v)) + } + + // Mutable pointer to the field. + pub fn mut_content(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(_)) = self.one_of_content { + } else { + self.one_of_content = ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(::std::string::String::new())); + } + match self.one_of_content { + ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_content(&mut self) -> ::std::string::String { + if self.has_content() { + match self.one_of_content.take() { + ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for CellNotificationData { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_content = ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_content { + match v { + &CellNotificationData_oneof_one_of_content::content(ref v) => { + my_size += ::protobuf::rt::string_size(4, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_content { + match v { + &CellNotificationData_oneof_one_of_content::content(ref v) => { + os.write_string(4, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CellNotificationData { + CellNotificationData::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &CellNotificationData| { &m.grid_id }, + |m: &mut CellNotificationData| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellNotificationData| { &m.field_id }, + |m: &mut CellNotificationData| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellNotificationData| { &m.row_id }, + |m: &mut CellNotificationData| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "content", + CellNotificationData::has_content, + CellNotificationData::get_content, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellNotificationData", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellNotificationData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellNotificationData::new) + } +} + +impl ::protobuf::Clear for CellNotificationData { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_id.clear(); + self.row_id.clear(); + self.one_of_content = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellNotificationData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellNotificationData { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedCell { // message fields @@ -5806,26 +6131,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07\ content\"b\n\x15CellIdentifierPayload\x12\x17\n\x07grid_id\x18\x01\x20\ \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ - \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"+\n\x0cRepeatedCell\ - \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11Cre\ - ateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06\ - GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlock\ - Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayl\ - oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_\ - row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\ - \"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ - \tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05fie\ - ld\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\ - \x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\ - \x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\ - \x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\ - \x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayl\ - oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_o\ - rders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrders\"A\n\x0fQ\ - ueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ - \x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"X\n\x19CreateSelectOption\ - Payload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionName\x12\x1a\ - \n\x08selected\x18\x02\x20\x01(\x08R\x08selectedb\x06proto3\ + \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"\x8f\x01\n\x14CellNot\ + ificationData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\ + \n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\ + \x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\ + \x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05i\ + tems\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\ + \x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\ + \n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\ + \x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\ + \x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\ + \n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gri\ + dId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\ + \x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0es\ + tart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_st\ + art_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.Repe\ + atedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\ + \x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrders\"A\n\x0fQueryRowPayloa\ + d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ + \x18\x03\x20\x01(\tR\x05rowId\"X\n\x19CreateSelectOptionPayload\x12\x1f\ + \n\x0boption_name\x18\x01\x20\x01(\tR\noptionName\x12\x1a\n\x08selected\ + \x18\x02\x20\x01(\x08R\x08selectedb\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 b3fcea8740..6be5bf1a64 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 @@ -75,6 +75,12 @@ message CellIdentifierPayload { string field_id = 2; string row_id = 3; } +message CellNotificationData { + string grid_id = 1; + string field_id = 2; + string row_id = 3; + oneof one_of_content { string content = 4; }; +} message RepeatedCell { repeated Cell items = 1; } From d09a5bf42b25d1c87195d5bf23baa89b562983f8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 08:33:10 +0800 Subject: [PATCH 100/179] chore: update and delete select option --- .../app_flowy/lib/startup/deps_resolver.dart | 1 - .../grid/cell_bloc/cell_service.dart | 41 - .../grid/cell_bloc/select_option_service.dart | 109 ++ .../grid/cell_bloc/selection_cell_bloc.dart | 9 +- .../grid/cell_bloc/selection_editor_bloc.dart | 140 ++- .../grid/field/field_editor_bloc.dart | 2 +- .../application/grid/field/field_service.dart | 3 +- .../application/grid/field/grid_listenr.dart | 2 +- .../field/type_option/multi_select_bloc.dart | 2 +- .../field/type_option/single_select_bloc.dart | 2 +- .../type_option/type_option_service.dart | 12 +- .../application/grid/row/row_service.dart | 3 +- .../cell/selection_cell/extension.dart | 17 +- .../cell/selection_cell/selection_cell.dart | 2 - .../cell/selection_cell/selection_editor.dart | 52 +- .../header/type_option/option_pannel.dart | 1 - .../src/flowy_overlay/overlay_container.dart | 4 +- .../dart_event/flowy-grid/dart_event.dart | 41 +- .../flowy_sdk/lib/dispatch/dispatch.dart | 3 + .../flowy-error-code/code.pbenum.dart | 4 + .../flowy-error-code/code.pbjson.dart | 4 +- .../flowy-grid-data-model/grid.pb.dart | 258 ----- .../flowy-grid-data-model/grid.pbjson.dart | 45 - .../flowy-grid-data-model/protobuf.dart | 2 +- .../protobuf/flowy-grid/cell_entities.pb.dart | 196 ++++ .../flowy-grid/cell_entities.pbenum.dart | 7 + .../flowy-grid/cell_entities.pbjson.dart | 43 + .../flowy-grid/cell_entities.pbserver.dart | 9 + .../flowy-grid/dart_notification.pbenum.dart | 4 +- .../flowy-grid/dart_notification.pbjson.dart | 4 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 14 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 9 +- .../flowy-grid/field_entities.pb.dart | 72 ++ .../flowy-grid/field_entities.pbenum.dart | 7 + .../flowy-grid/field_entities.pbjson.dart | 21 + .../flowy-grid/field_entities.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 3 + .../protobuf/flowy-grid/row_entities.pb.dart | 72 ++ .../flowy-grid/row_entities.pbenum.dart | 7 + .../flowy-grid/row_entities.pbjson.dart | 21 + .../flowy-grid/row_entities.pbserver.dart | 9 + .../flowy-grid/selection_type_option.pb.dart | 181 +++- .../selection_type_option.pbjson.dart | 20 +- frontend/rust-lib/dart-ffi/Cargo.toml | 2 +- frontend/rust-lib/flowy-grid/Flowy.toml | 9 +- .../flowy-grid/src/dart_notification.rs | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 155 +-- frontend/rust-lib/flowy-grid/src/event_map.rs | 24 +- .../src/protobuf/model/cell_entities.rs | 664 ++++++++++++ .../src/protobuf/model/dart_notification.rs | 12 +- .../src/protobuf/model/event_map.rs | 32 +- .../src/protobuf/model/field_entities.rs | 243 +++++ .../flowy-grid/src/protobuf/model/mod.rs | 9 + .../src/protobuf/model/row_entities.rs | 243 +++++ .../protobuf/model/selection_type_option.rs | 498 +++++++-- .../src/protobuf/proto/cell_entities.proto | 14 + .../protobuf/proto/dart_notification.proto | 2 +- .../src/protobuf/proto/event_map.proto | 7 +- .../src/protobuf/proto/field_entities.proto | 6 + .../src/protobuf/proto/row_entities.proto | 6 + .../proto/selection_type_option.proto | 6 + .../src/services/block_meta_editor.rs | 4 +- .../src/services/cell/cell_entities.rs | 69 ++ .../flowy-grid/src/services/cell/mod.rs | 3 + .../src/services/field/field_entities.rs | 30 + .../flowy-grid/src/services/field/mod.rs | 4 +- .../type_options/selection_type_option.rs | 154 ++- .../flowy-grid/src/services/grid_editor.rs | 50 +- .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../src/services/row/cell_data_operation.rs | 5 +- .../flowy-grid/src/services/row/mod.rs | 1 + .../src/services/row/row_entities.rs | 31 + .../flowy-grid/tests/grid/grid_test.rs | 13 +- shared-lib/flowy-error-code/src/code.rs | 4 + .../src/protobuf/model/code.rs | 15 +- .../src/protobuf/proto/code.proto | 2 + .../src/entities/grid.rs | 114 -- .../src/protobuf/model/grid.rs | 941 +---------------- .../src/protobuf/model/mod.rs | 3 + .../src/protobuf/model/type_option.rs | 978 ++++++++++++++++++ .../src/protobuf/proto/grid.proto | 17 - .../src/protobuf/proto/type_option.proto | 29 + .../src/client_grid/grid_meta_pad.rs | 113 +- 83 files changed, 4181 insertions(+), 1801 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/field_entities.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/row_entities.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/field_entities.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/row_entities.proto create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index c23b259bfe..58ad1cf9cc 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -188,7 +188,6 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (cellData, _) => SelectionCellBloc( - service: CellService(), cellData: cellData, ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index f7a0247a98..b36727adcc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -8,47 +8,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; class CellService { CellService(); - Future> addSelectOpiton({ - required String gridId, - required String fieldId, - required String rowId, - required String optionId, - }) { - final payload = SelectOptionChangesetPayload.create() - ..gridId = gridId - ..fieldId = fieldId - ..rowId = rowId - ..insertOptionId = optionId; - return GridEventApplySelectOptionChangeset(payload).send(); - } - - Future> getSelectOpitonContext({ - required String gridId, - required String fieldId, - required String rowId, - }) { - final payload = CellIdentifierPayload.create() - ..gridId = gridId - ..fieldId = fieldId - ..rowId = rowId; - - return GridEventGetSelectOptions(payload).send(); - } - - Future> removeSelectOpiton({ - required String gridId, - required String fieldId, - required String rowId, - required String optionId, - }) { - final payload = SelectOptionChangesetPayload.create() - ..gridId = gridId - ..fieldId = fieldId - ..rowId = rowId - ..deleteOptionId = optionId; - return GridEventApplySelectOptionChangeset(payload).send(); - } - Future> updateCell({ required String gridId, required String fieldId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart new file mode 100644 index 0000000000..ad0a1888b3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart @@ -0,0 +1,109 @@ +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; + +class SelectOptionService { + SelectOptionService(); + + Future> create({ + required String gridId, + required String fieldId, + required String rowId, + required String name, + }) { + return GridEventNewSelectOption(SelectOptionName.create()..name = name).send().then( + (result) { + return result.fold( + (option) { + final cellIdentifier = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + final payload = SelectOptionChangesetPayload.create() + ..insertOption = option + ..cellIdentifier = cellIdentifier; + return GridEventApplySelectOptionChangeset(payload).send(); + }, + (r) => right(r), + ); + }, + ); + } + + Future> insert({ + required String gridId, + required String fieldId, + required String rowId, + required SelectOption option, + }) { + final cellIdentifier = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + final payload = SelectOptionChangesetPayload.create() + ..insertOption = option + ..cellIdentifier = cellIdentifier; + return GridEventApplySelectOptionChangeset(payload).send(); + } + + Future> delete({ + required String gridId, + required String fieldId, + required String rowId, + required SelectOption option, + }) { + final cellIdentifier = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + + final payload = SelectOptionChangesetPayload.create() + ..deleteOption = option + ..cellIdentifier = cellIdentifier; + + return GridEventApplySelectOptionChangeset(payload).send(); + } + + Future> getOpitonContext({ + required String gridId, + required String fieldId, + required String rowId, + }) { + final payload = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + + return GridEventGetSelectOptionContext(payload).send(); + } + + Future> select({ + required String gridId, + required String fieldId, + required String rowId, + required String optionId, + }) { + final payload = SelectOptionCellChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..insertOptionId = optionId; + return GridEventApplySelectOptionCellChangeset(payload).send(); + } + + Future> remove({ + required String gridId, + required String fieldId, + required String rowId, + required String optionId, + }) { + final payload = SelectOptionCellChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..deleteOptionId = optionId; + return GridEventApplySelectOptionCellChangeset(payload).send(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 48c11622fe..b12b56b827 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,22 +1,21 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/select_option_service.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'cell_service.dart'; part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { - final CellService _service; + final SelectOptionService _service; final CellListener _listener; SelectionCellBloc({ - required CellService service, required CellData cellData, - }) : _service = service, + }) : _service = SelectOptionService(), _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(SelectionCellState.initial(cellData)) { on( @@ -41,7 +40,7 @@ class SelectionCellBloc extends Bloc { } void _loadOptions() async { - final result = await _service.getSelectOpitonContext( + final result = await _service.getOpitonContext( gridId: state.cellData.gridId, fieldId: state.cellData.field.id, rowId: state.cellData.rowId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 671dc7ae8a..c6396138a9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -1,56 +1,56 @@ +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; -import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; -import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'cell_service.dart'; +import 'select_option_service.dart'; part 'selection_editor_bloc.freezed.dart'; class SelectOptionEditorBloc extends Bloc { - final TypeOptionService _typeOptionService; - final CellService _cellService; - final FieldListener _listener; + final SelectOptionService _selectOptionService; + final FieldListener _fieldListener; + final CellListener _cellListener; SelectOptionEditorBloc({ required CellData cellData, required List options, required List selectedOptions, - }) : _cellService = CellService(), - _typeOptionService = TypeOptionService(fieldId: cellData.field.id), - _listener = FieldListener(fieldId: cellData.field.id), + }) : _selectOptionService = SelectOptionService(), + _fieldListener = FieldListener(fieldId: cellData.field.id), + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(SelectOptionEditorState.initial(cellData, options, selectedOptions)) { on( (event, emit) async { await event.map( initial: (_Initial value) async { _startListening(); - _loadOptions(); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(field: value.field)); _loadOptions(); }, didReceiveOptions: (_DidReceiveOptions value) { - emit(state.copyWith(options: value.options)); + emit(state.copyWith( + options: value.options, + selectedOptions: value.selectedOptions, + )); }, - newOption: (_NewOption value) async { - final result = await _typeOptionService.createOption(value.optionName, selected: true); - result.fold((l) => null, (err) => Log.error(err)); + newOption: (_NewOption value) { + _createOption(value.optionName); + }, + deleteOption: (_DeleteOption value) { + _deleteOption(value.option); + }, + updateOption: (_UpdateOption value) { + _updateOption(value.option); }, selectOption: (_SelectOption value) { - _cellService.addSelectOpiton( - gridId: state.gridId, - fieldId: state.field.id, - rowId: state.rowId, - optionId: value.optionId, - ); + _makeOptionAsSelected(value.optionId); }, ); }, @@ -59,39 +59,84 @@ class SelectOptionEditorBloc extends Bloc close() async { - await _listener.stop(); + await _fieldListener.stop(); + await _cellListener.stop(); return super.close(); } + void _createOption(String name) async { + final result = await _selectOptionService.create( + gridId: state.gridId, + fieldId: state.field.id, + rowId: state.rowId, + name: name, + ); + result.fold((l) => _loadOptions(), (err) => Log.error(err)); + } + + void _deleteOption(SelectOption option) async { + final result = await _selectOptionService.delete( + gridId: state.gridId, + fieldId: state.field.id, + rowId: state.rowId, + option: option, + ); + + result.fold((l) => null, (err) => Log.error(err)); + } + + void _updateOption(SelectOption option) async { + final result = await _selectOptionService.insert( + gridId: state.gridId, + fieldId: state.field.id, + rowId: state.rowId, + option: option, + ); + + result.fold((l) => null, (err) => Log.error(err)); + } + + void _makeOptionAsSelected(String optionId) { + _selectOptionService.select( + gridId: state.gridId, + fieldId: state.field.id, + rowId: state.rowId, + optionId: optionId, + ); + } + + void _loadOptions() async { + final result = await _selectOptionService.getOpitonContext( + gridId: state.gridId, + fieldId: state.field.id, + rowId: state.rowId, + ); + + result.fold( + (selectOptionContext) => add(SelectOptionEditorEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )), + (err) => Log.error(err), + ); + } + void _startListening() { - _listener.updateFieldNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier.addPublishListener((result) { + result.fold( + (notificationData) => _loadOptions(), + (err) => Log.error(err), + ); + }); + _cellListener.start(); + + _fieldListener.updateFieldNotifier.addPublishListener((result) { result.fold( (field) => add(SelectOptionEditorEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); }); - } - - void _loadOptions() async { - final result = await FieldContextLoaderAdaptor(gridId: state.gridId, field: state.field).load(); - result.fold( - (context) { - List options = []; - switch (state.field.fieldType) { - case FieldType.MultiSelect: - options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options); - break; - case FieldType.SingleSelect: - options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options); - break; - default: - Log.error("Invalid field type, expect single select or multiple select"); - break; - } - add(SelectOptionEditorEvent.didReceiveOptions(options)); - }, - (err) => Log.error(err), - ); + _fieldListener.start(); } } @@ -99,9 +144,12 @@ class SelectOptionEditorBloc extends Bloc options) = _DidReceiveOptions; + const factory SelectOptionEditorEvent.didReceiveOptions( + List options, List selectedOptions) = _DidReceiveOptions; const factory SelectOptionEditorEvent.newOption(String optionName) = _NewOption; const factory SelectOptionEditorEvent.selectOption(String optionId) = _SelectOption; + const factory SelectOptionEditorEvent.updateOption(SelectOption option) = _UpdateOption; + const factory SelectOptionEditorEvent.deleteOption(SelectOption option) = _DeleteOption; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart index 4556e17d38..dd27f66070 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart @@ -48,7 +48,7 @@ class FieldEditorBloc extends Bloc { () async => null, (field) async { field.name = state.fieldName; - final result = await service.createField( + final result = await service.insertField( field: field, typeOptionData: state.typeOptionData, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 61ccad6b81..3ea1c46062 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -4,6 +4,7 @@ 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:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; class FieldService { final String gridId; @@ -60,7 +61,7 @@ class FieldService { } // Create the field if it does not exist. Otherwise, update the field. - Future> createField({ + Future> insertField({ required Field field, List? typeOptionData, String? startFieldId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index fa92d84b79..434b343d8d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -24,7 +24,7 @@ class GridFieldsListener { void _handler(GridNotification ty, Either result) { switch (ty) { - case GridNotification.DidUpdateFields: + case GridNotification.DidUpdateGrid: result.fold( (payload) => updateFieldsNotifier.value = left(RepeatedField.fromBuffer(payload).items), (error) => updateFieldsNotifier.value = right(error), diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart index 0a96f5f69b..c5a55e20e1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart @@ -18,7 +18,7 @@ class MultiSelectTypeOptionBloc extends Bloc> createOption(String name, {bool selected = false}) { - final payload = CreateSelectOptionPayload.create() - ..optionName = name - ..selected = selected; - return GridEventCreateSelectOption(payload).send(); + Future> newOption(String name, {bool selected = false}) { + final payload = SelectOptionName.create()..name = name; + return GridEventNewSelectOption(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 8875f9dc98..8b2548b1b2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; class RowService { final String gridId; @@ -20,7 +21,7 @@ class RowService { } Future> getRow() { - QueryRowPayload payload = QueryRowPayload.create() + final payload = RowIdentifierPayload.create() ..gridId = gridId ..rowId = rowId; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index 9a91999a9d..1b3a81704d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -67,13 +67,16 @@ class SelectOptionTextField extends StatelessWidget { final FocusNode _focusNode; final TextEditingController _controller; final TextfieldTagsController tagController; - final LinkedHashMap optionMap; + final List options; + final LinkedHashMap selectedOptionMap; + final double distanceToText; final Function(String) onNewTag; SelectOptionTextField({ - required this.optionMap, + required this.options, + required this.selectedOptionMap, required this.distanceToText, required this.tagController, required this.onNewTag, @@ -91,12 +94,14 @@ class SelectOptionTextField extends StatelessWidget { return TextFieldTags( textEditingController: _controller, textfieldTagsController: tagController, - initialTags: optionMap.keys.toList(), + initialTags: selectedOptionMap.keys.toList(), focusNode: _focusNode, textSeparators: const [' ', ','], inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) { return ((context, sc, tags, onTagDelegate) { - tags.retainWhere((name) => optionMap.containsKey(name) == false); + tags.retainWhere((name) { + return options.where((option) => option.name == name).isEmpty; + }); if (tags.isNotEmpty) { assert(tags.length == 1); onNewTag(tags.first); @@ -133,11 +138,11 @@ class SelectOptionTextField extends StatelessWidget { } Widget? _renderTags(ScrollController sc) { - if (optionMap.isEmpty) { + if (selectedOptionMap.isEmpty) { return null; } - final children = optionMap.values.map((option) => SelectOptionTag(option: option)).toList(); + final children = selectedOptionMap.values.map((option) => SelectOptionTag(option: option)).toList(); return Padding( padding: const EdgeInsets.all(8.0), child: SingleChildScrollView( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 33a935d37e..2187325c95 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -1,7 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index d10a5a8cf8..1df2cd03b6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -3,10 +3,12 @@ import 'dart:collection'; import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; @@ -21,7 +23,7 @@ import 'extension.dart'; const double _editorPannelWidth = 300; -class SelectOptionEditor extends StatelessWidget { +class SelectOptionEditor extends StatelessWidget with FlowyOverlayDelegate { final CellData cellData; final List options; final List selectedOptions; @@ -44,7 +46,7 @@ class SelectOptionEditor extends StatelessWidget { cellData: cellData, options: options, selectedOptions: selectedOptions, - ), + )..add(const SelectOptionEditorEvent.initial()), child: BlocBuilder( builder: (context, state) { return CustomScrollView( @@ -83,12 +85,16 @@ class SelectOptionEditor extends StatelessWidget { identifier: SelectOptionEditor.identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomWithCenterAligned, + delegate: editor, ); } static void hide(BuildContext context) { FlowyOverlay.of(context).remove(identifier()); } + + @override + bool asBarrier() => true; } class _OptionList extends StatelessWidget { @@ -126,18 +132,19 @@ class _TextField extends StatelessWidget { Widget build(BuildContext context) { return BlocConsumer( listener: (context, state) {}, - buildWhen: (previous, current) => previous.field.id != current.field.id, builder: (context, state) { final optionMap = LinkedHashMap.fromIterable(state.selectedOptions, key: (option) => option.name, value: (option) => option); + return SizedBox( height: 42, child: SelectOptionTextField( - optionMap: optionMap, + options: state.options, + selectedOptionMap: optionMap, distanceToText: _editorPannelWidth * 0.7, tagController: _tagController, - onNewTag: (newTagName) { - context.read().add(SelectOptionEditorEvent.newOption(newTagName)); + onNewTag: (tagName) { + context.read().add(SelectOptionEditorEvent.newOption(tagName)); }, ), ); @@ -188,7 +195,12 @@ class _SelectOptionCell extends StatelessWidget { ]; if (onHover) { - children.add(svgWidget("editor/details", color: theme.iconColor)); + children.add(FlowyIconButton( + width: 28, + onPressed: () => _showEditOptionPannel(context), + iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), + icon: svgWidget("editor/details", color: theme.iconColor), + )); } return Padding( @@ -200,4 +212,30 @@ class _SelectOptionCell extends StatelessWidget { ), ); } + + void _showEditOptionPannel(BuildContext context) { + final pannel = EditSelectOptionPannel( + option: option, + onDeleted: () { + context.read().add(SelectOptionEditorEvent.deleteOption(option)); + }, + onUpdated: (updatedOption) { + context.read().add(SelectOptionEditorEvent.updateOption(updatedOption)); + }, + // key: ValueKey(option.id), + ); + final overlayIdentifier = pannel.toString(); + + FlowyOverlay.of(context).remove(overlayIdentifier); + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: pannel, + constraints: BoxConstraints.loose(const Size(200, 300)), + ), + identifier: overlayIdentifier, + anchorContext: context, + anchorDirection: AnchorDirection.rightWithCenterAligned, + anchorOffset: Offset(2 * overlayContainerPadding.left, 0), + ); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart index 7c93f63ee7..034accfb19 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart @@ -165,7 +165,6 @@ class _OptionList extends StatelessWidget { delegate.hideOverlay(context); context.read().add(OptionPannelEvent.updateOption(updatedOption)); }, - key: ValueKey(option.id), ); delegate.showOverlay(context, pannel); }, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart index b1f18b6695..85de2c71a7 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart @@ -3,6 +3,8 @@ import 'package:flowy_infra_ui/style_widget/decoration.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +const overlayContainerPadding = EdgeInsets.all(12); + class OverlayContainer extends StatelessWidget { final Widget child; final BoxConstraints? constraints; @@ -10,7 +12,7 @@ class OverlayContainer extends StatelessWidget { const OverlayContainer({ required this.child, this.constraints, - this.padding = const EdgeInsets.all(12), + this.padding = overlayContainerPadding, Key? key, }) : super(key: key); 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 2a23cfad4a..3003b4c6f8 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 @@ -154,13 +154,13 @@ class GridEventGetEditFieldContext { } } -class GridEventCreateSelectOption { - CreateSelectOptionPayload request; - GridEventCreateSelectOption(this.request); +class GridEventNewSelectOption { + SelectOptionName request; + GridEventNewSelectOption(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.CreateSelectOption.toString() + ..event = GridEvent.NewSelectOption.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) @@ -171,13 +171,13 @@ class GridEventCreateSelectOption { } } -class GridEventGetSelectOptions { +class GridEventGetSelectOptionContext { CellIdentifierPayload request; - GridEventGetSelectOptions(this.request); + GridEventGetSelectOptionContext(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.GetSelectOptions.toString() + ..event = GridEvent.GetSelectOptionContext.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) @@ -188,6 +188,23 @@ class GridEventGetSelectOptions { } } +class GridEventApplySelectOptionChangeset { + SelectOptionChangesetPayload request; + GridEventApplySelectOptionChangeset(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.ApplySelectOptionChangeset.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventCreateRow { CreateRowPayload request; GridEventCreateRow(this.request); @@ -206,7 +223,7 @@ class GridEventCreateRow { } class GridEventGetRow { - QueryRowPayload request; + RowIdentifierPayload request; GridEventGetRow(this.request); Future> send() { @@ -239,13 +256,13 @@ class GridEventUpdateCell { } } -class GridEventApplySelectOptionChangeset { - SelectOptionChangesetPayload request; - GridEventApplySelectOptionChangeset(this.request); +class GridEventApplySelectOptionCellChangeset { + SelectOptionCellChangesetPayload request; + GridEventApplySelectOptionCellChangeset(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.ApplySelectOptionChangeset.toString() + ..event = GridEvent.ApplySelectOptionCellChangeset.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) 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 e2be9f11a2..db010e9f75 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -4,6 +4,9 @@ import 'package:flowy_sdk/log.dart'; // ignore: unnecessary_import import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-net/event.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index a638e65405..0d1eabddf8 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -49,6 +49,8 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode FieldIdIsEmpty = ErrorCode._(440, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldIdIsEmpty'); static const ErrorCode FieldDoesNotExist = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldDoesNotExist'); static const ErrorCode SelectOptionNameIsEmpty = ErrorCode._(442, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SelectOptionNameIsEmpty'); + static const ErrorCode FieldNotExists = ErrorCode._(443, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldNotExists'); + static const ErrorCode FieldInvalidOperation = ErrorCode._(444, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldInvalidOperation'); static const ErrorCode TypeOptionDataIsEmpty = ErrorCode._(450, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionDataIsEmpty'); static const ErrorCode InvalidData = ErrorCode._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); @@ -92,6 +94,8 @@ class ErrorCode extends $pb.ProtobufEnum { FieldIdIsEmpty, FieldDoesNotExist, SelectOptionNameIsEmpty, + FieldNotExists, + FieldInvalidOperation, TypeOptionDataIsEmpty, InvalidData, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 625e2d9572..fa6ba4076b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -51,10 +51,12 @@ const ErrorCode$json = const { const {'1': 'FieldIdIsEmpty', '2': 440}, const {'1': 'FieldDoesNotExist', '2': 441}, const {'1': 'SelectOptionNameIsEmpty', '2': 442}, + const {'1': 'FieldNotExists', '2': 443}, + const {'1': 'FieldInvalidOperation', '2': 444}, const {'1': 'TypeOptionDataIsEmpty', '2': 450}, const {'1': 'InvalidData', '2': 500}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxIUCg9PcHRpb25JZElzRW1wdHkQrwMSEwoORmllbGRJZElzRW1wdHkQuAMSFgoRRmllbGREb2VzTm90RXhpc3QQuQMSHAoXU2VsZWN0T3B0aW9uTmFtZUlzRW1wdHkQugMSGgoVVHlwZU9wdGlvbkRhdGFJc0VtcHR5EMIDEhAKC0ludmFsaWREYXRhEPQD'); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxIUCg9PcHRpb25JZElzRW1wdHkQrwMSEwoORmllbGRJZElzRW1wdHkQuAMSFgoRRmllbGREb2VzTm90RXhpc3QQuQMSHAoXU2VsZWN0T3B0aW9uTmFtZUlzRW1wdHkQugMSEwoORmllbGROb3RFeGlzdHMQuwMSGgoVRmllbGRJbnZhbGlkT3BlcmF0aW9uELwDEhoKFVR5cGVPcHRpb25EYXRhSXNFbXB0eRDCAxIQCgtJbnZhbGlkRGF0YRD0Aw=='); 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 2cd87115bf..e27e019be3 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 @@ -205,67 +205,6 @@ class Field extends $pb.GeneratedMessage { void clearWidth() => clearField(7); } -class FieldIdentifierPayload extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldIdentifierPayload', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..hasRequiredFields = false - ; - - FieldIdentifierPayload._() : super(); - factory FieldIdentifierPayload({ - $core.String? fieldId, - $core.String? gridId, - }) { - final _result = create(); - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (gridId != null) { - _result.gridId = gridId; - } - return _result; - } - factory FieldIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FieldIdentifierPayload.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') - FieldIdentifierPayload clone() => FieldIdentifierPayload()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FieldIdentifierPayload copyWith(void Function(FieldIdentifierPayload) updates) => super.copyWith((message) => updates(message as FieldIdentifierPayload)) as FieldIdentifierPayload; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FieldIdentifierPayload create() => FieldIdentifierPayload._(); - FieldIdentifierPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static FieldIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static FieldIdentifierPayload? _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.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); -} - 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') @@ -1024,81 +963,6 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(2); } -class CellIdentifierPayload extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellIdentifierPayload', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..hasRequiredFields = false - ; - - CellIdentifierPayload._() : super(); - factory CellIdentifierPayload({ - $core.String? gridId, - $core.String? fieldId, - $core.String? rowId, - }) { - final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (rowId != null) { - _result.rowId = rowId; - } - return _result; - } - factory CellIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CellIdentifierPayload.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') - CellIdentifierPayload clone() => CellIdentifierPayload()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CellIdentifierPayload copyWith(void Function(CellIdentifierPayload) updates) => super.copyWith((message) => updates(message as CellIdentifierPayload)) as CellIdentifierPayload; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CellIdentifierPayload create() => CellIdentifierPayload._(); - CellIdentifierPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CellIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CellIdentifierPayload? _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 fieldId => $_getSZ(1); - @$pb.TagNumber(2) - set fieldId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasFieldId() => $_has(1); - @$pb.TagNumber(2) - void clearFieldId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get rowId => $_getSZ(2); - @$pb.TagNumber(3) - set rowId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasRowId() => $_has(2); - @$pb.TagNumber(3) - void clearRowId() => clearField(3); -} - enum CellNotificationData_OneOfContent { content, notSet @@ -1679,125 +1543,3 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage { $core.List get blockOrders => $_getList(1); } -class QueryRowPayload extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..hasRequiredFields = false - ; - - QueryRowPayload._() : super(); - factory QueryRowPayload({ - $core.String? gridId, - $core.String? rowId, - }) { - final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } - if (rowId != null) { - _result.rowId = rowId; - } - return _result; - } - factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory QueryRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static QueryRowPayload create() => QueryRowPayload._(); - QueryRowPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static QueryRowPayload? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get gridId => $_getSZ(0); - @$pb.TagNumber(1) - set gridId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasGridId() => $_has(0); - @$pb.TagNumber(1) - void clearGridId() => clearField(1); - - @$pb.TagNumber(3) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(3) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(3) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(3) - void clearRowId() => clearField(3); -} - -class CreateSelectOptionPayload extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'selected') - ..hasRequiredFields = false - ; - - CreateSelectOptionPayload._() : super(); - factory CreateSelectOptionPayload({ - $core.String? optionName, - $core.bool? selected, - }) { - final _result = create(); - if (optionName != null) { - _result.optionName = optionName; - } - if (selected != null) { - _result.selected = selected; - } - return _result; - } - factory CreateSelectOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CreateSelectOptionPayload.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') - CreateSelectOptionPayload clone() => CreateSelectOptionPayload()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CreateSelectOptionPayload copyWith(void Function(CreateSelectOptionPayload) updates) => super.copyWith((message) => updates(message as CreateSelectOptionPayload)) as CreateSelectOptionPayload; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CreateSelectOptionPayload create() => CreateSelectOptionPayload._(); - CreateSelectOptionPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CreateSelectOptionPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CreateSelectOptionPayload? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get optionName => $_getSZ(0); - @$pb.TagNumber(1) - set optionName($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasOptionName() => $_has(0); - @$pb.TagNumber(1) - void clearOptionName() => clearField(1); - - @$pb.TagNumber(2) - $core.bool get selected => $_getBF(1); - @$pb.TagNumber(2) - set selected($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasSelected() => $_has(1); - @$pb.TagNumber(2) - void clearSelected() => clearField(2); -} - 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 cf58ec74a2..3cd228af79 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 @@ -36,17 +36,6 @@ const Field$json = const { /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aA=='); -@$core.Deprecated('Use fieldIdentifierPayloadDescriptor instead') -const FieldIdentifierPayload$json = const { - '1': 'FieldIdentifierPayload', - '2': const [ - const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, - ], -}; - -/// Descriptor for `FieldIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldIdentifierPayloadDescriptor = $convert.base64Decode('ChZGaWVsZElkZW50aWZpZXJQYXlsb2FkEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZA=='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -203,18 +192,6 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); -@$core.Deprecated('Use cellIdentifierPayloadDescriptor instead') -const CellIdentifierPayload$json = const { - '1': 'CellIdentifierPayload', - '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, - ], -}; - -/// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); @$core.Deprecated('Use cellNotificationDataDescriptor instead') const CellNotificationData$json = const { '1': 'CellNotificationData', @@ -323,25 +300,3 @@ const QueryGridBlocksPayload$json = const { /// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM='); -@$core.Deprecated('Use queryRowPayloadDescriptor instead') -const QueryRowPayload$json = const { - '1': 'QueryRowPayload', - '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, - ], -}; - -/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); -@$core.Deprecated('Use createSelectOptionPayloadDescriptor instead') -const CreateSelectOptionPayload$json = const { - '1': 'CreateSelectOptionPayload', - '2': const [ - const {'1': 'option_name', '3': 1, '4': 1, '5': 9, '10': 'optionName'}, - const {'1': 'selected', '3': 2, '4': 1, '5': 8, '10': 'selected'}, - ], -}; - -/// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1lEhoKCHNlbGVjdGVkGAIgASgIUghzZWxlY3RlZA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart index 2c253e0494..6cedb363ef 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart @@ -1,3 +1,3 @@ -// Auto-generated, do not edit +// Auto-generated, do not edit export './grid.pb.dart'; export './meta.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart new file mode 100644 index 0000000000..259fcf1422 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart @@ -0,0 +1,196 @@ +/// +// Generated code. Do not modify. +// source: cell_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 + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class CreateSelectOptionPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) + ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellIdentifier', subBuilder: CellIdentifierPayload.create) + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') + ..hasRequiredFields = false + ; + + CreateSelectOptionPayload._() : super(); + factory CreateSelectOptionPayload({ + CellIdentifierPayload? cellIdentifier, + $core.String? optionName, + }) { + final _result = create(); + if (cellIdentifier != null) { + _result.cellIdentifier = cellIdentifier; + } + if (optionName != null) { + _result.optionName = optionName; + } + return _result; + } + factory CreateSelectOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateSelectOptionPayload.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') + CreateSelectOptionPayload clone() => CreateSelectOptionPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateSelectOptionPayload copyWith(void Function(CreateSelectOptionPayload) updates) => super.copyWith((message) => updates(message as CreateSelectOptionPayload)) as CreateSelectOptionPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateSelectOptionPayload create() => CreateSelectOptionPayload._(); + CreateSelectOptionPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateSelectOptionPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateSelectOptionPayload? _defaultInstance; + + @$pb.TagNumber(1) + CellIdentifierPayload get cellIdentifier => $_getN(0); + @$pb.TagNumber(1) + set cellIdentifier(CellIdentifierPayload v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasCellIdentifier() => $_has(0); + @$pb.TagNumber(1) + void clearCellIdentifier() => clearField(1); + @$pb.TagNumber(1) + CellIdentifierPayload ensureCellIdentifier() => $_ensure(0); + + @$pb.TagNumber(2) + $core.String get optionName => $_getSZ(1); + @$pb.TagNumber(2) + set optionName($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasOptionName() => $_has(1); + @$pb.TagNumber(2) + void clearOptionName() => clearField(2); +} + +class CellIdentifierPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellIdentifierPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..hasRequiredFields = false + ; + + CellIdentifierPayload._() : super(); + factory CellIdentifierPayload({ + $core.String? gridId, + $core.String? fieldId, + $core.String? rowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (rowId != null) { + _result.rowId = rowId; + } + return _result; + } + factory CellIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellIdentifierPayload.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') + CellIdentifierPayload clone() => CellIdentifierPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellIdentifierPayload copyWith(void Function(CellIdentifierPayload) updates) => super.copyWith((message) => updates(message as CellIdentifierPayload)) as CellIdentifierPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellIdentifierPayload create() => CellIdentifierPayload._(); + CellIdentifierPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellIdentifierPayload? _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 fieldId => $_getSZ(1); + @$pb.TagNumber(2) + set fieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get rowId => $_getSZ(2); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(2); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); +} + +class SelectOptionName extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionName', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..hasRequiredFields = false + ; + + SelectOptionName._() : super(); + factory SelectOptionName({ + $core.String? name, + }) { + final _result = create(); + if (name != null) { + _result.name = name; + } + return _result; + } + factory SelectOptionName.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOptionName.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') + SelectOptionName clone() => SelectOptionName()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOptionName copyWith(void Function(SelectOptionName) updates) => super.copyWith((message) => updates(message as SelectOptionName)) as SelectOptionName; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOptionName create() => SelectOptionName._(); + SelectOptionName createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOptionName getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOptionName? _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); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbenum.dart new file mode 100644 index 0000000000..a53c27b1fe --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: cell_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-grid/cell_entities.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart new file mode 100644 index 0000000000..ac0c9add9c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart @@ -0,0 +1,43 @@ +/// +// Generated code. Do not modify. +// source: cell_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 + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use createSelectOptionPayloadDescriptor instead') +const CreateSelectOptionPayload$json = const { + '1': 'CreateSelectOptionPayload', + '2': const [ + const {'1': 'cell_identifier', '3': 1, '4': 1, '5': 11, '6': '.CellIdentifierPayload', '10': 'cellIdentifier'}, + const {'1': 'option_name', '3': 2, '4': 1, '5': 9, '10': 'optionName'}, + ], +}; + +/// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEj8KD2NlbGxfaWRlbnRpZmllchgBIAEoCzIWLkNlbGxJZGVudGlmaWVyUGF5bG9hZFIOY2VsbElkZW50aWZpZXISHwoLb3B0aW9uX25hbWUYAiABKAlSCm9wdGlvbk5hbWU='); +@$core.Deprecated('Use cellIdentifierPayloadDescriptor instead') +const CellIdentifierPayload$json = const { + '1': 'CellIdentifierPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + ], +}; + +/// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); +@$core.Deprecated('Use selectOptionNameDescriptor instead') +const SelectOptionName$json = const { + '1': 'SelectOptionName', + '2': const [ + const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `SelectOptionName`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionNameDescriptor = $convert.base64Decode('ChBTZWxlY3RPcHRpb25OYW1lEhIKBG5hbWUYASABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbserver.dart new file mode 100644 index 0000000000..a0f185bca8 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: cell_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 'cell_entities.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 8f1cd90c29..4331fef2a7 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -15,7 +15,7 @@ class GridNotification extends $pb.ProtobufEnum { static const GridNotification DidUpdateBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateBlock'); static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); static const GridNotification DidUpdateCell = GridNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateCell'); - static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields'); + static const GridNotification DidUpdateGrid = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGrid'); static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); static const $core.List values = [ @@ -24,7 +24,7 @@ class GridNotification extends $pb.ProtobufEnum { DidUpdateBlock, DidUpdateRow, DidUpdateCell, - DidUpdateFields, + DidUpdateGrid, DidUpdateField, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 504d7e56f5..ed6bbdc2d4 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -17,10 +17,10 @@ const GridNotification$json = const { const {'1': 'DidUpdateBlock', '2': 20}, const {'1': 'DidUpdateRow', '2': 30}, const {'1': 'DidUpdateCell', '2': 31}, - const {'1': 'DidUpdateFields', '2': 40}, + const {'1': 'DidUpdateGrid', '2': 40}, const {'1': 'DidUpdateField', '2': 41}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEQoNRGlkVXBkYXRlQ2VsbBAfEhMKD0RpZFVwZGF0ZUZpZWxkcxAoEhIKDkRpZFVwZGF0ZUZpZWxkECk='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEQoNRGlkVXBkYXRlQ2VsbBAfEhEKDURpZFVwZGF0ZUdyaWQQKBISCg5EaWRVcGRhdGVGaWVsZBAp'); 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 4c8cff633b..7c190dcd98 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 @@ -19,12 +19,13 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent SwitchToField = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SwitchToField'); static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext'); - static const GridEvent CreateSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateSelectOption'); - static const GridEvent GetSelectOptions = GridEvent._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetSelectOptions'); + static const GridEvent NewSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewSelectOption'); + static const GridEvent GetSelectOptionContext = GridEvent._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetSelectOptionContext'); + static const GridEvent ApplySelectOptionChangeset = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); - static const GridEvent ApplySelectOptionChangeset = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); + static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); static const $core.List values = [ GetGridData, @@ -36,12 +37,13 @@ class GridEvent extends $pb.ProtobufEnum { SwitchToField, DuplicateField, GetEditFieldContext, - CreateSelectOption, - GetSelectOptions, + NewSelectOption, + GetSelectOptionContext, + ApplySelectOptionChangeset, CreateRow, GetRow, UpdateCell, - ApplySelectOptionChangeset, + ApplySelectOptionCellChangeset, ]; 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 017dc4b1aa..1c07877726 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 @@ -21,14 +21,15 @@ const GridEvent$json = const { const {'1': 'SwitchToField', '2': 14}, const {'1': 'DuplicateField', '2': 15}, const {'1': 'GetEditFieldContext', '2': 16}, - const {'1': 'CreateSelectOption', '2': 30}, - const {'1': 'GetSelectOptions', '2': 31}, + const {'1': 'NewSelectOption', '2': 30}, + const {'1': 'GetSelectOptionContext', '2': 31}, + const {'1': 'ApplySelectOptionChangeset', '2': 32}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, const {'1': 'UpdateCell', '2': 70}, - const {'1': 'ApplySelectOptionChangeset', '2': 71}, + const {'1': 'ApplySelectOptionCellChangeset', '2': 71}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEhQKEEdldFNlbGVjdE9wdGlvbnMQHxINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxIOCgpVcGRhdGVDZWxsEEYSHgoaQXBwbHlTZWxlY3RPcHRpb25DaGFuZ2VzZXQQRw=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg4KClVwZGF0ZUNlbGwQRhIiCh5BcHBseVNlbGVjdE9wdGlvbkNlbGxDaGFuZ2VzZXQQRw=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pb.dart new file mode 100644 index 0000000000..a99c401bf2 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pb.dart @@ -0,0 +1,72 @@ +/// +// Generated code. Do not modify. +// source: field_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 + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class FieldIdentifierPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldIdentifierPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..hasRequiredFields = false + ; + + FieldIdentifierPayload._() : super(); + factory FieldIdentifierPayload({ + $core.String? fieldId, + $core.String? gridId, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (gridId != null) { + _result.gridId = gridId; + } + return _result; + } + factory FieldIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldIdentifierPayload.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') + FieldIdentifierPayload clone() => FieldIdentifierPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldIdentifierPayload copyWith(void Function(FieldIdentifierPayload) updates) => super.copyWith((message) => updates(message as FieldIdentifierPayload)) as FieldIdentifierPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldIdentifierPayload create() => FieldIdentifierPayload._(); + FieldIdentifierPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldIdentifierPayload? _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.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); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbenum.dart new file mode 100644 index 0000000000..e9ca968924 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: field_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-grid/field_entities.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbjson.dart new file mode 100644 index 0000000000..e8b768c21a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbjson.dart @@ -0,0 +1,21 @@ +/// +// Generated code. Do not modify. +// source: field_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 + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use fieldIdentifierPayloadDescriptor instead') +const FieldIdentifierPayload$json = const { + '1': 'FieldIdentifierPayload', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + ], +}; + +/// Descriptor for `FieldIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldIdentifierPayloadDescriptor = $convert.base64Decode('ChZGaWVsZElkZW50aWZpZXJQYXlsb2FkEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbserver.dart new file mode 100644 index 0000000000..9c99be4d1d --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/field_entities.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: field_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 'field_entities.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index 874107f9be..af6583c106 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,7 +1,10 @@ // Auto-generated, do not edit +export './field_entities.pb.dart'; export './number_type_option.pb.dart'; export './dart_notification.pb.dart'; export './selection_type_option.pb.dart'; +export './row_entities.pb.dart'; +export './cell_entities.pb.dart'; export './checkbox_type_option.pb.dart'; export './event_map.pb.dart'; export './text_type_option.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pb.dart new file mode 100644 index 0000000000..8f8c278b12 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pb.dart @@ -0,0 +1,72 @@ +/// +// Generated code. Do not modify. +// source: row_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 + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class RowIdentifierPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowIdentifierPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..hasRequiredFields = false + ; + + RowIdentifierPayload._() : super(); + factory RowIdentifierPayload({ + $core.String? gridId, + $core.String? rowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (rowId != null) { + _result.rowId = rowId; + } + return _result; + } + factory RowIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RowIdentifierPayload.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') + RowIdentifierPayload clone() => RowIdentifierPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RowIdentifierPayload copyWith(void Function(RowIdentifierPayload) updates) => super.copyWith((message) => updates(message as RowIdentifierPayload)) as RowIdentifierPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RowIdentifierPayload create() => RowIdentifierPayload._(); + RowIdentifierPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RowIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RowIdentifierPayload? _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(3) + $core.String get rowId => $_getSZ(1); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(1); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbenum.dart new file mode 100644 index 0000000000..a53bd30bf7 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: row_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-grid/row_entities.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbjson.dart new file mode 100644 index 0000000000..b5dd44d360 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbjson.dart @@ -0,0 +1,21 @@ +/// +// Generated code. Do not modify. +// source: row_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 + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use rowIdentifierPayloadDescriptor instead') +const RowIdentifierPayload$json = const { + '1': 'RowIdentifierPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + ], +}; + +/// Descriptor for `RowIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowIdentifierPayloadDescriptor = $convert.base64Decode('ChRSb3dJZGVudGlmaWVyUGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAMgASgJUgVyb3dJZA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbserver.dart new file mode 100644 index 0000000000..905505060a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/row_entities.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: row_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 'row_entities.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart index 350806f275..5b2576d7eb 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -9,6 +9,8 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'cell_entities.pb.dart' as $0; + import 'selection_type_option.pbenum.dart'; export 'selection_type_option.pbenum.dart'; @@ -198,59 +200,49 @@ class SelectOption extends $pb.GeneratedMessage { void clearColor() => clearField(3); } -enum SelectOptionChangesetPayload_OneOfInsertOptionId { - insertOptionId, +enum SelectOptionChangesetPayload_OneOfInsertOption { + insertOption, notSet } -enum SelectOptionChangesetPayload_OneOfDeleteOptionId { - deleteOptionId, +enum SelectOptionChangesetPayload_OneOfDeleteOption { + deleteOption, notSet } class SelectOptionChangesetPayload extends $pb.GeneratedMessage { - static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfInsertOptionId> _SelectOptionChangesetPayload_OneOfInsertOptionIdByTag = { - 4 : SelectOptionChangesetPayload_OneOfInsertOptionId.insertOptionId, - 0 : SelectOptionChangesetPayload_OneOfInsertOptionId.notSet + static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfInsertOption> _SelectOptionChangesetPayload_OneOfInsertOptionByTag = { + 2 : SelectOptionChangesetPayload_OneOfInsertOption.insertOption, + 0 : SelectOptionChangesetPayload_OneOfInsertOption.notSet }; - static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfDeleteOptionId> _SelectOptionChangesetPayload_OneOfDeleteOptionIdByTag = { - 5 : SelectOptionChangesetPayload_OneOfDeleteOptionId.deleteOptionId, - 0 : SelectOptionChangesetPayload_OneOfDeleteOptionId.notSet + static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfDeleteOption> _SelectOptionChangesetPayload_OneOfDeleteOptionByTag = { + 3 : SelectOptionChangesetPayload_OneOfDeleteOption.deleteOption, + 0 : SelectOptionChangesetPayload_OneOfDeleteOption.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionChangesetPayload', createEmptyInstance: create) - ..oo(0, [4]) - ..oo(1, [5]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') - ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') + ..oo(0, [2]) + ..oo(1, [3]) + ..aOM<$0.CellIdentifierPayload>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellIdentifier', subBuilder: $0.CellIdentifierPayload.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOption', subBuilder: SelectOption.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOption', subBuilder: SelectOption.create) ..hasRequiredFields = false ; SelectOptionChangesetPayload._() : super(); factory SelectOptionChangesetPayload({ - $core.String? gridId, - $core.String? rowId, - $core.String? fieldId, - $core.String? insertOptionId, - $core.String? deleteOptionId, + $0.CellIdentifierPayload? cellIdentifier, + SelectOption? insertOption, + SelectOption? deleteOption, }) { final _result = create(); - if (gridId != null) { - _result.gridId = gridId; + if (cellIdentifier != null) { + _result.cellIdentifier = cellIdentifier; } - if (rowId != null) { - _result.rowId = rowId; + if (insertOption != null) { + _result.insertOption = insertOption; } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (insertOptionId != null) { - _result.insertOptionId = insertOptionId; - } - if (deleteOptionId != null) { - _result.deleteOptionId = deleteOptionId; + if (deleteOption != null) { + _result.deleteOption = deleteOption; } return _result; } @@ -275,10 +267,127 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { static SelectOptionChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); static SelectOptionChangesetPayload? _defaultInstance; - SelectOptionChangesetPayload_OneOfInsertOptionId whichOneOfInsertOptionId() => _SelectOptionChangesetPayload_OneOfInsertOptionIdByTag[$_whichOneof(0)]!; + SelectOptionChangesetPayload_OneOfInsertOption whichOneOfInsertOption() => _SelectOptionChangesetPayload_OneOfInsertOptionByTag[$_whichOneof(0)]!; + void clearOneOfInsertOption() => clearField($_whichOneof(0)); + + SelectOptionChangesetPayload_OneOfDeleteOption whichOneOfDeleteOption() => _SelectOptionChangesetPayload_OneOfDeleteOptionByTag[$_whichOneof(1)]!; + void clearOneOfDeleteOption() => clearField($_whichOneof(1)); + + @$pb.TagNumber(1) + $0.CellIdentifierPayload get cellIdentifier => $_getN(0); + @$pb.TagNumber(1) + set cellIdentifier($0.CellIdentifierPayload v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasCellIdentifier() => $_has(0); + @$pb.TagNumber(1) + void clearCellIdentifier() => clearField(1); + @$pb.TagNumber(1) + $0.CellIdentifierPayload ensureCellIdentifier() => $_ensure(0); + + @$pb.TagNumber(2) + SelectOption get insertOption => $_getN(1); + @$pb.TagNumber(2) + set insertOption(SelectOption v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasInsertOption() => $_has(1); + @$pb.TagNumber(2) + void clearInsertOption() => clearField(2); + @$pb.TagNumber(2) + SelectOption ensureInsertOption() => $_ensure(1); + + @$pb.TagNumber(3) + SelectOption get deleteOption => $_getN(2); + @$pb.TagNumber(3) + set deleteOption(SelectOption v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasDeleteOption() => $_has(2); + @$pb.TagNumber(3) + void clearDeleteOption() => clearField(3); + @$pb.TagNumber(3) + SelectOption ensureDeleteOption() => $_ensure(2); +} + +enum SelectOptionCellChangesetPayload_OneOfInsertOptionId { + insertOptionId, + notSet +} + +enum SelectOptionCellChangesetPayload_OneOfDeleteOptionId { + deleteOptionId, + notSet +} + +class SelectOptionCellChangesetPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, SelectOptionCellChangesetPayload_OneOfInsertOptionId> _SelectOptionCellChangesetPayload_OneOfInsertOptionIdByTag = { + 4 : SelectOptionCellChangesetPayload_OneOfInsertOptionId.insertOptionId, + 0 : SelectOptionCellChangesetPayload_OneOfInsertOptionId.notSet + }; + static const $core.Map<$core.int, SelectOptionCellChangesetPayload_OneOfDeleteOptionId> _SelectOptionCellChangesetPayload_OneOfDeleteOptionIdByTag = { + 5 : SelectOptionCellChangesetPayload_OneOfDeleteOptionId.deleteOptionId, + 0 : SelectOptionCellChangesetPayload_OneOfDeleteOptionId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionCellChangesetPayload', createEmptyInstance: create) + ..oo(0, [4]) + ..oo(1, [5]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') + ..hasRequiredFields = false + ; + + SelectOptionCellChangesetPayload._() : super(); + factory SelectOptionCellChangesetPayload({ + $core.String? gridId, + $core.String? rowId, + $core.String? fieldId, + $core.String? insertOptionId, + $core.String? deleteOptionId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (rowId != null) { + _result.rowId = rowId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (insertOptionId != null) { + _result.insertOptionId = insertOptionId; + } + if (deleteOptionId != null) { + _result.deleteOptionId = deleteOptionId; + } + return _result; + } + factory SelectOptionCellChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOptionCellChangesetPayload.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') + SelectOptionCellChangesetPayload clone() => SelectOptionCellChangesetPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOptionCellChangesetPayload copyWith(void Function(SelectOptionCellChangesetPayload) updates) => super.copyWith((message) => updates(message as SelectOptionCellChangesetPayload)) as SelectOptionCellChangesetPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOptionCellChangesetPayload create() => SelectOptionCellChangesetPayload._(); + SelectOptionCellChangesetPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOptionCellChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOptionCellChangesetPayload? _defaultInstance; + + SelectOptionCellChangesetPayload_OneOfInsertOptionId whichOneOfInsertOptionId() => _SelectOptionCellChangesetPayload_OneOfInsertOptionIdByTag[$_whichOneof(0)]!; void clearOneOfInsertOptionId() => clearField($_whichOneof(0)); - SelectOptionChangesetPayload_OneOfDeleteOptionId whichOneOfDeleteOptionId() => _SelectOptionChangesetPayload_OneOfDeleteOptionIdByTag[$_whichOneof(1)]!; + SelectOptionCellChangesetPayload_OneOfDeleteOptionId whichOneOfDeleteOptionId() => _SelectOptionCellChangesetPayload_OneOfDeleteOptionIdByTag[$_whichOneof(1)]!; void clearOneOfDeleteOptionId() => clearField($_whichOneof(1)); @$pb.TagNumber(1) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart index 04c44a3004..7a160d582d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -63,6 +63,22 @@ final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxT @$core.Deprecated('Use selectOptionChangesetPayloadDescriptor instead') const SelectOptionChangesetPayload$json = const { '1': 'SelectOptionChangesetPayload', + '2': const [ + const {'1': 'cell_identifier', '3': 1, '4': 1, '5': 11, '6': '.CellIdentifierPayload', '10': 'cellIdentifier'}, + const {'1': 'insert_option', '3': 2, '4': 1, '5': 11, '6': '.SelectOption', '9': 0, '10': 'insertOption'}, + const {'1': 'delete_option', '3': 3, '4': 1, '5': 11, '6': '.SelectOption', '9': 1, '10': 'deleteOption'}, + ], + '8': const [ + const {'1': 'one_of_insert_option'}, + const {'1': 'one_of_delete_option'}, + ], +}; + +/// Descriptor for `SelectOptionChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEj8KD2NlbGxfaWRlbnRpZmllchgBIAEoCzIWLkNlbGxJZGVudGlmaWVyUGF5bG9hZFIOY2VsbElkZW50aWZpZXISNAoNaW5zZXJ0X29wdGlvbhgCIAEoCzINLlNlbGVjdE9wdGlvbkgAUgxpbnNlcnRPcHRpb24SNAoNZGVsZXRlX29wdGlvbhgDIAEoCzINLlNlbGVjdE9wdGlvbkgBUgxkZWxldGVPcHRpb25CFgoUb25lX29mX2luc2VydF9vcHRpb25CFgoUb25lX29mX2RlbGV0ZV9vcHRpb24='); +@$core.Deprecated('Use selectOptionCellChangesetPayloadDescriptor instead') +const SelectOptionCellChangesetPayload$json = const { + '1': 'SelectOptionCellChangesetPayload', '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'}, @@ -76,8 +92,8 @@ const SelectOptionChangesetPayload$json = const { ], }; -/// Descriptor for `SelectOptionChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEioKEGluc2VydF9vcHRpb25faWQYBCABKAlIAFIOaW5zZXJ0T3B0aW9uSWQSKgoQZGVsZXRlX29wdGlvbl9pZBgFIAEoCUgBUg5kZWxldGVPcHRpb25JZEIZChdvbmVfb2ZfaW5zZXJ0X29wdGlvbl9pZEIZChdvbmVfb2ZfZGVsZXRlX29wdGlvbl9pZA=='); +/// Descriptor for `SelectOptionCellChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionCellChangesetPayloadDescriptor = $convert.base64Decode('CiBTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0UGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIqChBpbnNlcnRfb3B0aW9uX2lkGAQgASgJSABSDmluc2VydE9wdGlvbklkEioKEGRlbGV0ZV9vcHRpb25faWQYBSABKAlIAVIOZGVsZXRlT3B0aW9uSWRCGQoXb25lX29mX2luc2VydF9vcHRpb25faWRCGQoXb25lX29mX2RlbGV0ZV9vcHRpb25faWQ='); @$core.Deprecated('Use selectOptionContextDescriptor instead') const SelectOptionContext$json = const { '1': 'SelectOptionContext', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 143dc76b1e..df26694331 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" name = "dart_ffi" # this value will change depending on the target os # default static lib -crate-type = ["cdylib"] +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index d0b6c8dec5..b0b15a1a2a 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,10 @@ -proto_crates = ["src/event_map.rs", "src/services/field/type_options", "src/dart_notification.rs"] +proto_crates = [ + "src/event_map.rs", + "src/services/field/type_options", + "src/services/field/field_entities.rs", + "src/services/cell/cell_entities.rs", + "src/services/row/row_entities.rs", + "src/dart_notification.rs" +] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 914b3088f5..cc910e30c6 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -9,7 +9,7 @@ pub enum GridNotification { DidUpdateBlock = 20, DidUpdateRow = 30, DidUpdateCell = 31, - DidUpdateFields = 40, + DidUpdateGrid = 40, DidUpdateField = 41, } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 2a8bb86103..3d46349240 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,10 +1,11 @@ use crate::manager::GridManager; -use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_json_str, MultiSelectTypeOption, SelectOption, - SelectOptionChangesetParams, SelectOptionChangesetPayload, SelectOptionContext, SingleSelectTypeOption, -}; +use crate::services::cell::cell_entities::*; +use crate::services::field::field_entities::*; +use crate::services::field::type_options::*; +use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str}; use crate::services::grid_editor::ClientGridEditor; -use flowy_error::{FlowyError, FlowyResult}; +use crate::services::row::row_entities::*; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -76,7 +77,7 @@ pub(crate) async fn delete_field_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let params: FieldIdentifierParams = data.into_inner().try_into()?; + let params: FieldIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; let _ = editor.delete_field(¶ms.field_id).await?; Ok(()) @@ -93,10 +94,7 @@ pub(crate) async fn switch_to_field_handler( .switch_to_field_type(¶ms.field_id, ¶ms.field_type) .await?; - let field_meta = editor - .get_field_metas(Some(vec![params.field_id.as_str()])) - .await? - .pop(); + let field_meta = editor.get_field_meta(¶ms.field_id).await; let edit_context = make_field_edit_context( ¶ms.grid_id, Some(params.field_id), @@ -113,58 +111,12 @@ pub(crate) async fn duplicate_field_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let params: FieldIdentifierParams = data.into_inner().try_into()?; + let params: FieldIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; let _ = editor.duplicate_field(¶ms.field_id).await?; Ok(()) } -#[tracing::instrument(level = "debug", skip(data), err)] -pub(crate) async fn create_select_option_handler( - data: Data, -) -> DataResult { - let params: CreateSelectOptionParams = data.into_inner().try_into()?; - data_result(SelectOption::new(¶ms.option_name)) -} - -#[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn get_select_option_handler( - data: Data, - manager: AppData>, -) -> DataResult { - let params: CellIdentifier = data.into_inner().try_into()?; - let editor = manager.get_grid_editor(¶ms.grid_id)?; - match editor - .get_field_metas(Some(vec![params.field_id.as_str()])) - .await? - .pop() - { - None => { - tracing::error!("Can't find the corresponding field with id: {}", params.field_id); - data_result(SelectOptionContext::default()) - } - Some(field_meta) => { - let cell_meta = editor.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; - match field_meta.field_type { - FieldType::SingleSelect => { - let type_option = SingleSelectTypeOption::from(&field_meta); - let select_option_context = type_option.select_option_context(&cell_meta); - data_result(select_option_context) - } - FieldType::MultiSelect => { - let type_option = MultiSelectTypeOption::from(&field_meta); - let select_option_context = type_option.select_option_context(&cell_meta); - data_result(select_option_context) - } - ty => { - tracing::error!("Unsupported field type: {:?} for this handler", ty); - data_result(SelectOptionContext::default()) - } - } - } - } -} - #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_field_context_handler( data: Data, @@ -207,7 +159,7 @@ async fn get_or_create_field_meta( ) -> FlowyResult { match field_id { None => editor.create_next_field_meta(field_type).await, - Some(field_id) => match editor.get_field_metas(Some(vec![field_id.as_str()])).await?.pop() { + Some(field_id) => match editor.get_field_meta(&field_id).await { None => editor.create_next_field_meta(field_type).await, Some(field_meta) => Ok(field_meta), }, @@ -216,10 +168,10 @@ async fn get_or_create_field_meta( #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_row_handler( - data: Data, + data: Data, manager: AppData>, ) -> DataResult { - let params: QueryRowParams = data.into_inner().try_into()?; + let params: RowIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; match editor.get_row(¶ms.row_id).await? { None => Err(FlowyError::record_not_found().context("Can not find the row")), @@ -250,13 +202,92 @@ pub(crate) async fn update_cell_handler( } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn apply_select_option_changeset_handler( +pub(crate) async fn new_select_option_handler(data: Data) -> DataResult { + let params = data.into_inner(); + data_result(SelectOption::new(¶ms.name)) +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn select_option_changeset_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let params: SelectOptionChangesetParams = data.into_inner().try_into()?; + let changeset: SelectOptionChangeset = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(&changeset.cell_identifier.grid_id)?; + + if let Some(mut field_meta) = editor.get_field_meta(&changeset.cell_identifier.field_id).await { + let mut type_option = select_option_operation(&field_meta)?; + let mut cell_data = None; + if let Some(option) = changeset.insert_option { + cell_data = Some(SelectOptionCellChangeset::from_insert(&option.id).cell_data()); + type_option.insert_option(option); + } + + if let Some(option) = changeset.delete_option { + cell_data = Some(SelectOptionCellChangeset::from_delete(&option.id).cell_data()); + type_option.delete_option(option); + } + + field_meta.insert_type_option_entry(&*type_option); + let _ = editor.replace_field(field_meta).await?; + + let changeset = CellMetaChangeset { + grid_id: changeset.cell_identifier.grid_id, + row_id: changeset.cell_identifier.row_id, + field_id: changeset.cell_identifier.field_id, + data: cell_data, + }; + let _ = editor.update_cell(changeset).await?; + } + Ok(()) +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn get_select_option_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CellIdentifier = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_field_meta(¶ms.field_id).await { + None => { + tracing::error!("Can't find the corresponding field with id: {}", params.field_id); + data_result(SelectOptionContext::default()) + } + Some(field_meta) => { + let cell_meta = editor.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; + let type_option = select_option_operation(&field_meta)?; + let option_context = type_option.option_context(&cell_meta); + data_result(option_context) + } + } +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn select_option_cell_changeset_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; let changeset: CellMetaChangeset = params.into(); let _ = editor.update_cell(changeset).await?; Ok(()) } + +fn select_option_operation(field_meta: &FieldMeta) -> FlowyResult> { + match &field_meta.field_type { + FieldType::SingleSelect => { + let type_option = SingleSelectTypeOption::from(field_meta); + Ok(Box::new(type_option)) + } + FieldType::MultiSelect => { + let type_option = MultiSelectTypeOption::from(field_meta); + Ok(Box::new(type_option)) + } + ty => { + tracing::error!("Unsupported field type: {:?} for this handler", ty); + Err(ErrorCode::FieldInvalidOperation.into()) + } + } +} diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 2af4b28e35..711ad46255 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -23,11 +23,12 @@ pub fn create(grid_manager: Arc) -> Module { // Cell .event(GridEvent::UpdateCell, update_cell_handler) // SelectOption - .event(GridEvent::CreateSelectOption, create_select_option_handler) - .event(GridEvent::GetSelectOptions, get_select_option_handler) + .event(GridEvent::NewSelectOption, new_select_option_handler) + .event(GridEvent::ApplySelectOptionChangeset, select_option_changeset_handler) + .event(GridEvent::GetSelectOptionContext, get_select_option_handler) .event( - GridEvent::ApplySelectOptionChangeset, - apply_select_option_changeset_handler, + GridEvent::ApplySelectOptionCellChangeset, + select_option_cell_changeset_handler, ) .event(GridEvent::GetEditFieldContext, get_field_context_handler); @@ -64,21 +65,24 @@ pub enum GridEvent { #[event(input = "GetEditFieldContextPayload", output = "EditFieldContext")] GetEditFieldContext = 16, - #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] - CreateSelectOption = 30, + #[event(input = "SelectOptionName", output = "SelectOption")] + NewSelectOption = 30, #[event(input = "CellIdentifierPayload", output = "SelectOptionContext")] - GetSelectOptions = 31, + GetSelectOptionContext = 31, + + #[event(input = "SelectOptionChangesetPayload")] + ApplySelectOptionChangeset = 32, #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 50, - #[event(input = "QueryRowPayload", output = "Row")] + #[event(input = "RowIdentifierPayload", output = "Row")] GetRow = 51, #[event(input = "CellMetaChangeset")] UpdateCell = 70, - #[event(input = "SelectOptionChangesetPayload")] - ApplySelectOptionChangeset = 71, + #[event(input = "SelectOptionCellChangesetPayload")] + ApplySelectOptionCellChangeset = 71, } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs new file mode 100644 index 0000000000..107f783e59 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs @@ -0,0 +1,664 @@ +// 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_entities.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 CreateSelectOptionPayload { + // message fields + pub cell_identifier: ::protobuf::SingularPtrField, + pub option_name: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateSelectOptionPayload { + fn default() -> &'a CreateSelectOptionPayload { + ::default_instance() + } +} + +impl CreateSelectOptionPayload { + pub fn new() -> CreateSelectOptionPayload { + ::std::default::Default::default() + } + + // .CellIdentifierPayload cell_identifier = 1; + + + pub fn get_cell_identifier(&self) -> &CellIdentifierPayload { + self.cell_identifier.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_cell_identifier(&mut self) { + self.cell_identifier.clear(); + } + + pub fn has_cell_identifier(&self) -> bool { + self.cell_identifier.is_some() + } + + // Param is passed by value, moved + pub fn set_cell_identifier(&mut self, v: CellIdentifierPayload) { + self.cell_identifier = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_cell_identifier(&mut self) -> &mut CellIdentifierPayload { + if self.cell_identifier.is_none() { + self.cell_identifier.set_default(); + } + self.cell_identifier.as_mut().unwrap() + } + + // Take field + pub fn take_cell_identifier(&mut self) -> CellIdentifierPayload { + self.cell_identifier.take().unwrap_or_else(|| CellIdentifierPayload::new()) + } + + // string option_name = 2; + + + pub fn get_option_name(&self) -> &str { + &self.option_name + } + pub fn clear_option_name(&mut self) { + self.option_name.clear(); + } + + // Param is passed by value, moved + pub fn set_option_name(&mut self, v: ::std::string::String) { + self.option_name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_option_name(&mut self) -> &mut ::std::string::String { + &mut self.option_name + } + + // Take field + pub fn take_option_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.option_name, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for CreateSelectOptionPayload { + fn is_initialized(&self) -> bool { + for v in &self.cell_identifier { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.cell_identifier)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.option_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 let Some(ref v) = self.cell_identifier.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.option_name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.option_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 let Some(ref v) = self.cell_identifier.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.option_name.is_empty() { + os.write_string(2, &self.option_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() -> CreateSelectOptionPayload { + CreateSelectOptionPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "cell_identifier", + |m: &CreateSelectOptionPayload| { &m.cell_identifier }, + |m: &mut CreateSelectOptionPayload| { &mut m.cell_identifier }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "option_name", + |m: &CreateSelectOptionPayload| { &m.option_name }, + |m: &mut CreateSelectOptionPayload| { &mut m.option_name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateSelectOptionPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateSelectOptionPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateSelectOptionPayload::new) + } +} + +impl ::protobuf::Clear for CreateSelectOptionPayload { + fn clear(&mut self) { + self.cell_identifier.clear(); + self.option_name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateSelectOptionPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateSelectOptionPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct CellIdentifierPayload { + // message fields + pub grid_id: ::std::string::String, + pub field_id: ::std::string::String, + pub row_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellIdentifierPayload { + fn default() -> &'a CellIdentifierPayload { + ::default_instance() + } +} + +impl CellIdentifierPayload { + pub fn new() -> CellIdentifierPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string row_id = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for CellIdentifierPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + 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() -> CellIdentifierPayload { + CellIdentifierPayload::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: &CellIdentifierPayload| { &m.grid_id }, + |m: &mut CellIdentifierPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellIdentifierPayload| { &m.field_id }, + |m: &mut CellIdentifierPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellIdentifierPayload| { &m.row_id }, + |m: &mut CellIdentifierPayload| { &mut m.row_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellIdentifierPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellIdentifierPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellIdentifierPayload::new) + } +} + +impl ::protobuf::Clear for CellIdentifierPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_id.clear(); + self.row_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellIdentifierPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SelectOptionName { + // 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 SelectOptionName { + fn default() -> &'a SelectOptionName { + ::default_instance() + } +} + +impl SelectOptionName { + pub fn new() -> SelectOptionName { + ::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 SelectOptionName { + 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() -> SelectOptionName { + SelectOptionName::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: &SelectOptionName| { &m.name }, + |m: &mut SelectOptionName| { &mut m.name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionName", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOptionName { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionName::new) + } +} + +impl ::protobuf::Clear for SelectOptionName { + fn clear(&mut self) { + self.name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOptionName { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionName { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x13cell_entities.proto\"}\n\x19CreateSelectOptionPayload\x12?\n\x0fce\ + ll_identifier\x18\x01\x20\x01(\x0b2\x16.CellIdentifierPayloadR\x0ecellId\ + entifier\x12\x1f\n\x0boption_name\x18\x02\x20\x01(\tR\noptionName\"b\n\ + \x15CellIdentifierPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ + idId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06r\ + ow_id\x18\x03\x20\x01(\tR\x05rowId\"&\n\x10SelectOptionName\x12\x12\n\ + \x04name\x18\x01\x20\x01(\tR\x04nameb\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/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index e02f234e9f..d5eaa2a6d8 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -30,7 +30,7 @@ pub enum GridNotification { DidUpdateBlock = 20, DidUpdateRow = 30, DidUpdateCell = 31, - DidUpdateFields = 40, + DidUpdateGrid = 40, DidUpdateField = 41, } @@ -46,7 +46,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { 20 => ::std::option::Option::Some(GridNotification::DidUpdateBlock), 30 => ::std::option::Option::Some(GridNotification::DidUpdateRow), 31 => ::std::option::Option::Some(GridNotification::DidUpdateCell), - 40 => ::std::option::Option::Some(GridNotification::DidUpdateFields), + 40 => ::std::option::Option::Some(GridNotification::DidUpdateGrid), 41 => ::std::option::Option::Some(GridNotification::DidUpdateField), _ => ::std::option::Option::None } @@ -59,7 +59,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { GridNotification::DidUpdateBlock, GridNotification::DidUpdateRow, GridNotification::DidUpdateCell, - GridNotification::DidUpdateFields, + GridNotification::DidUpdateGrid, GridNotification::DidUpdateField, ]; values @@ -89,11 +89,11 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x95\x01\n\x10GridNotification\x12\x0b\n\ + \n\x17dart_notification.proto*\x93\x01\n\x10GridNotification\x12\x0b\n\ \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x12\n\x0eDidUp\ dateBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUpdate\ - Cell\x10\x1f\x12\x13\n\x0fDidUpdateFields\x10(\x12\x12\n\x0eDidUpdateFie\ - ld\x10)b\x06proto3\ + Cell\x10\x1f\x12\x11\n\rDidUpdateGrid\x10(\x12\x12\n\x0eDidUpdateField\ + \x10)b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 72a0601391..ef26608bf1 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 @@ -34,12 +34,13 @@ pub enum GridEvent { SwitchToField = 14, DuplicateField = 15, GetEditFieldContext = 16, - CreateSelectOption = 30, - GetSelectOptions = 31, + NewSelectOption = 30, + GetSelectOptionContext = 31, + ApplySelectOptionChangeset = 32, CreateRow = 50, GetRow = 51, UpdateCell = 70, - ApplySelectOptionChangeset = 71, + ApplySelectOptionCellChangeset = 71, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -58,12 +59,13 @@ impl ::protobuf::ProtobufEnum for GridEvent { 14 => ::std::option::Option::Some(GridEvent::SwitchToField), 15 => ::std::option::Option::Some(GridEvent::DuplicateField), 16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext), - 30 => ::std::option::Option::Some(GridEvent::CreateSelectOption), - 31 => ::std::option::Option::Some(GridEvent::GetSelectOptions), + 30 => ::std::option::Option::Some(GridEvent::NewSelectOption), + 31 => ::std::option::Option::Some(GridEvent::GetSelectOptionContext), + 32 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), 70 => ::std::option::Option::Some(GridEvent::UpdateCell), - 71 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), + 71 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), _ => ::std::option::Option::None } } @@ -79,12 +81,13 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::SwitchToField, GridEvent::DuplicateField, GridEvent::GetEditFieldContext, - GridEvent::CreateSelectOption, - GridEvent::GetSelectOptions, + GridEvent::NewSelectOption, + GridEvent::GetSelectOptionContext, + GridEvent::ApplySelectOptionChangeset, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, - GridEvent::ApplySelectOptionChangeset, + GridEvent::ApplySelectOptionCellChangeset, ]; values } @@ -113,14 +116,15 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xaa\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xd1\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ - ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x16\n\x12Creat\ - eSelectOption\x10\x1e\x12\x14\n\x10GetSelectOptions\x10\x1f\x12\r\n\tCre\ - ateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\x1e\n\ - \x1aApplySelectOptionChangeset\x10Gb\x06proto3\ + ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\ + lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x1e\n\ + \x1aApplySelectOptionChangeset\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\ + \x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\"\n\x1eApplySelectOptionC\ + ellChangeset\x10Gb\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/field_entities.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/field_entities.rs new file mode 100644 index 0000000000..fa4edcc070 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/field_entities.rs @@ -0,0 +1,243 @@ +// 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 `field_entities.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 FieldIdentifierPayload { + // message fields + pub field_id: ::std::string::String, + pub grid_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a FieldIdentifierPayload { + fn default() -> &'a FieldIdentifierPayload { + ::default_instance() + } +} + +impl FieldIdentifierPayload { + pub fn new() -> FieldIdentifierPayload { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string 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()) + } +} + +impl ::protobuf::Message for FieldIdentifierPayload { + 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 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_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.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_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() -> FieldIdentifierPayload { + FieldIdentifierPayload::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: &FieldIdentifierPayload| { &m.field_id }, + |m: &mut FieldIdentifierPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &FieldIdentifierPayload| { &m.grid_id }, + |m: &mut FieldIdentifierPayload| { &mut m.grid_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldIdentifierPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldIdentifierPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldIdentifierPayload::new) + } +} + +impl ::protobuf::Clear for FieldIdentifierPayload { + fn clear(&mut self) { + self.field_id.clear(); + self.grid_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldIdentifierPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldIdentifierPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x14field_entities.proto\"L\n\x16FieldIdentifierPayload\x12\x19\n\x08f\ + ield_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\ + \x01(\tR\x06gridIdb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index 8408c120c1..99d0ecd1b6 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,6 +1,9 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit +mod field_entities; +pub use field_entities::*; + mod number_type_option; pub use number_type_option::*; @@ -10,6 +13,12 @@ pub use dart_notification::*; mod selection_type_option; pub use selection_type_option::*; +mod row_entities; +pub use row_entities::*; + +mod cell_entities; +pub use cell_entities::*; + mod checkbox_type_option; pub use checkbox_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/row_entities.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/row_entities.rs new file mode 100644 index 0000000000..0bcf1323c6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/row_entities.rs @@ -0,0 +1,243 @@ +// 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 `row_entities.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 RowIdentifierPayload { + // message fields + pub grid_id: ::std::string::String, + pub row_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RowIdentifierPayload { + fn default() -> &'a RowIdentifierPayload { + ::default_instance() + } +} + +impl RowIdentifierPayload { + pub fn new() -> RowIdentifierPayload { + ::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 = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for RowIdentifierPayload { + 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)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RowIdentifierPayload { + RowIdentifierPayload::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: &RowIdentifierPayload| { &m.grid_id }, + |m: &mut RowIdentifierPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &RowIdentifierPayload| { &m.row_id }, + |m: &mut RowIdentifierPayload| { &mut m.row_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RowIdentifierPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RowIdentifierPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RowIdentifierPayload::new) + } +} + +impl ::protobuf::Clear for RowIdentifierPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.row_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RowIdentifierPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RowIdentifierPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x12row_entities.proto\"F\n\x14RowIdentifierPayload\x12\x17\n\x07grid_\ + id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ + \x05rowIdb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index 7a65da1171..ea45e6ac6e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -660,12 +660,10 @@ impl ::protobuf::reflect::ProtobufValue for SelectOption { #[derive(PartialEq,Clone,Default)] pub struct SelectOptionChangesetPayload { // message fields - pub grid_id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, + pub cell_identifier: ::protobuf::SingularPtrField, // message oneof groups - pub one_of_insert_option_id: ::std::option::Option, - pub one_of_delete_option_id: ::std::option::Option, + pub one_of_insert_option: ::std::option::Option, + pub one_of_delete_option: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -678,13 +676,13 @@ impl<'a> ::std::default::Default for &'a SelectOptionChangesetPayload { } #[derive(Clone,PartialEq,Debug)] -pub enum SelectOptionChangesetPayload_oneof_one_of_insert_option_id { - insert_option_id(::std::string::String), +pub enum SelectOptionChangesetPayload_oneof_one_of_insert_option { + insert_option(SelectOption), } #[derive(Clone,PartialEq,Debug)] -pub enum SelectOptionChangesetPayload_oneof_one_of_delete_option_id { - delete_option_id(::std::string::String), +pub enum SelectOptionChangesetPayload_oneof_one_of_delete_option { + delete_option(SelectOption), } impl SelectOptionChangesetPayload { @@ -692,6 +690,361 @@ impl SelectOptionChangesetPayload { ::std::default::Default::default() } + // .CellIdentifierPayload cell_identifier = 1; + + + pub fn get_cell_identifier(&self) -> &super::cell_entities::CellIdentifierPayload { + self.cell_identifier.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_cell_identifier(&mut self) { + self.cell_identifier.clear(); + } + + pub fn has_cell_identifier(&self) -> bool { + self.cell_identifier.is_some() + } + + // Param is passed by value, moved + pub fn set_cell_identifier(&mut self, v: super::cell_entities::CellIdentifierPayload) { + self.cell_identifier = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_cell_identifier(&mut self) -> &mut super::cell_entities::CellIdentifierPayload { + if self.cell_identifier.is_none() { + self.cell_identifier.set_default(); + } + self.cell_identifier.as_mut().unwrap() + } + + // Take field + pub fn take_cell_identifier(&mut self) -> super::cell_entities::CellIdentifierPayload { + self.cell_identifier.take().unwrap_or_else(|| super::cell_entities::CellIdentifierPayload::new()) + } + + // .SelectOption insert_option = 2; + + + pub fn get_insert_option(&self) -> &SelectOption { + match self.one_of_insert_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(ref v)) => v, + _ => ::default_instance(), + } + } + pub fn clear_insert_option(&mut self) { + self.one_of_insert_option = ::std::option::Option::None; + } + + pub fn has_insert_option(&self) -> bool { + match self.one_of_insert_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_insert_option(&mut self, v: SelectOption) { + self.one_of_insert_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(v)) + } + + // Mutable pointer to the field. + pub fn mut_insert_option(&mut self) -> &mut SelectOption { + if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(_)) = self.one_of_insert_option { + } else { + self.one_of_insert_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(SelectOption::new())); + } + match self.one_of_insert_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_insert_option(&mut self) -> SelectOption { + if self.has_insert_option() { + match self.one_of_insert_option.take() { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(v)) => v, + _ => panic!(), + } + } else { + SelectOption::new() + } + } + + // .SelectOption delete_option = 3; + + + pub fn get_delete_option(&self) -> &SelectOption { + match self.one_of_delete_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v)) => v, + _ => ::default_instance(), + } + } + pub fn clear_delete_option(&mut self) { + self.one_of_delete_option = ::std::option::Option::None; + } + + pub fn has_delete_option(&self) -> bool { + match self.one_of_delete_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_delete_option(&mut self, v: SelectOption) { + self.one_of_delete_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(v)) + } + + // Mutable pointer to the field. + pub fn mut_delete_option(&mut self) -> &mut SelectOption { + if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(_)) = self.one_of_delete_option { + } else { + self.one_of_delete_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(SelectOption::new())); + } + match self.one_of_delete_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_delete_option(&mut self) -> SelectOption { + if self.has_delete_option() { + match self.one_of_delete_option.take() { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(v)) => v, + _ => panic!(), + } + } else { + SelectOption::new() + } + } +} + +impl ::protobuf::Message for SelectOptionChangesetPayload { + fn is_initialized(&self) -> bool { + for v in &self.cell_identifier { + if !v.is_initialized() { + return false; + } + }; + if let Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(ref v)) = self.one_of_insert_option { + if !v.is_initialized() { + return false; + } + } + if let Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v)) = self.one_of_delete_option { + if !v.is_initialized() { + return false; + } + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.cell_identifier)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_insert_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(is.read_message()?)); + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_delete_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(is.read_message()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.cell_identifier.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let ::std::option::Option::Some(ref v) = self.one_of_insert_option { + match v { + &SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_delete_option { + match v { + &SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.cell_identifier.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_insert_option { + match v { + &SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(ref v) => { + 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 ::std::option::Option::Some(ref v) = self.one_of_delete_option { + match v { + &SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v) => { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SelectOptionChangesetPayload { + SelectOptionChangesetPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "cell_identifier", + |m: &SelectOptionChangesetPayload| { &m.cell_identifier }, + |m: &mut SelectOptionChangesetPayload| { &mut m.cell_identifier }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, SelectOption>( + "insert_option", + SelectOptionChangesetPayload::has_insert_option, + SelectOptionChangesetPayload::get_insert_option, + )); + fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, SelectOption>( + "delete_option", + SelectOptionChangesetPayload::has_delete_option, + SelectOptionChangesetPayload::get_delete_option, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionChangesetPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOptionChangesetPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionChangesetPayload::new) + } +} + +impl ::protobuf::Clear for SelectOptionChangesetPayload { + fn clear(&mut self) { + self.cell_identifier.clear(); + self.one_of_insert_option = ::std::option::Option::None; + self.one_of_delete_option = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOptionChangesetPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionChangesetPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SelectOptionCellChangesetPayload { + // message fields + pub grid_id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_insert_option_id: ::std::option::Option, + pub one_of_delete_option_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOptionCellChangesetPayload { + fn default() -> &'a SelectOptionCellChangesetPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id { + insert_option_id(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id { + delete_option_id(::std::string::String), +} + +impl SelectOptionCellChangesetPayload { + pub fn new() -> SelectOptionCellChangesetPayload { + ::std::default::Default::default() + } + // string grid_id = 1; @@ -775,7 +1128,7 @@ impl SelectOptionChangesetPayload { pub fn get_insert_option_id(&self) -> &str { match self.one_of_insert_option_id { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v)) => v, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v)) => v, _ => "", } } @@ -785,24 +1138,24 @@ impl SelectOptionChangesetPayload { pub fn has_insert_option_id(&self) -> bool { match self.one_of_insert_option_id { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(..)) => true, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_insert_option_id(&mut self, v: ::std::string::String) { - self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) } // Mutable pointer to the field. pub fn mut_insert_option_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(_)) = self.one_of_insert_option_id { + if let ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(_)) = self.one_of_insert_option_id { } else { - self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(::std::string::String::new())); + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(::std::string::String::new())); } match self.one_of_insert_option_id { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref mut v)) => v, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref mut v)) => v, _ => panic!(), } } @@ -811,7 +1164,7 @@ impl SelectOptionChangesetPayload { pub fn take_insert_option_id(&mut self) -> ::std::string::String { if self.has_insert_option_id() { match self.one_of_insert_option_id.take() { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) => v, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) => v, _ => panic!(), } } else { @@ -824,7 +1177,7 @@ impl SelectOptionChangesetPayload { pub fn get_delete_option_id(&self) -> &str { match self.one_of_delete_option_id { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v)) => v, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v)) => v, _ => "", } } @@ -834,24 +1187,24 @@ impl SelectOptionChangesetPayload { pub fn has_delete_option_id(&self) -> bool { match self.one_of_delete_option_id { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(..)) => true, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_delete_option_id(&mut self, v: ::std::string::String) { - self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) } // Mutable pointer to the field. pub fn mut_delete_option_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(_)) = self.one_of_delete_option_id { + if let ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(_)) = self.one_of_delete_option_id { } else { - self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(::std::string::String::new())); + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(::std::string::String::new())); } match self.one_of_delete_option_id { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref mut v)) => v, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref mut v)) => v, _ => panic!(), } } @@ -860,7 +1213,7 @@ impl SelectOptionChangesetPayload { pub fn take_delete_option_id(&mut self) -> ::std::string::String { if self.has_delete_option_id() { match self.one_of_delete_option_id.take() { - ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) => v, + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) => v, _ => panic!(), } } else { @@ -869,7 +1222,7 @@ impl SelectOptionChangesetPayload { } } -impl ::protobuf::Message for SelectOptionChangesetPayload { +impl ::protobuf::Message for SelectOptionCellChangesetPayload { fn is_initialized(&self) -> bool { true } @@ -891,13 +1244,13 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); }, 5 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(is.read_string()?)); + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(is.read_string()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -922,14 +1275,14 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { } if let ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { match v { - &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { + &SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { my_size += ::protobuf::rt::string_size(4, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { match v { - &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { + &SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { my_size += ::protobuf::rt::string_size(5, &v); }, }; @@ -951,14 +1304,14 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { } if let ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { match v { - &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { + &SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { os.write_string(4, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { match v { - &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { + &SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { os.write_string(5, v)?; }, }; @@ -993,8 +1346,8 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { Self::descriptor_static() } - fn new() -> SelectOptionChangesetPayload { - SelectOptionChangesetPayload::new() + fn new() -> SelectOptionCellChangesetPayload { + SelectOptionCellChangesetPayload::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1003,44 +1356,44 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &SelectOptionChangesetPayload| { &m.grid_id }, - |m: &mut SelectOptionChangesetPayload| { &mut m.grid_id }, + |m: &SelectOptionCellChangesetPayload| { &m.grid_id }, + |m: &mut SelectOptionCellChangesetPayload| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", - |m: &SelectOptionChangesetPayload| { &m.row_id }, - |m: &mut SelectOptionChangesetPayload| { &mut m.row_id }, + |m: &SelectOptionCellChangesetPayload| { &m.row_id }, + |m: &mut SelectOptionCellChangesetPayload| { &mut m.row_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "field_id", - |m: &SelectOptionChangesetPayload| { &m.field_id }, - |m: &mut SelectOptionChangesetPayload| { &mut m.field_id }, + |m: &SelectOptionCellChangesetPayload| { &m.field_id }, + |m: &mut SelectOptionCellChangesetPayload| { &mut m.field_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "insert_option_id", - SelectOptionChangesetPayload::has_insert_option_id, - SelectOptionChangesetPayload::get_insert_option_id, + SelectOptionCellChangesetPayload::has_insert_option_id, + SelectOptionCellChangesetPayload::get_insert_option_id, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "delete_option_id", - SelectOptionChangesetPayload::has_delete_option_id, - SelectOptionChangesetPayload::get_delete_option_id, + SelectOptionCellChangesetPayload::has_delete_option_id, + SelectOptionCellChangesetPayload::get_delete_option_id, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOptionChangesetPayload", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionCellChangesetPayload", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static SelectOptionChangesetPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOptionChangesetPayload::new) + fn default_instance() -> &'static SelectOptionCellChangesetPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionCellChangesetPayload::new) } } -impl ::protobuf::Clear for SelectOptionChangesetPayload { +impl ::protobuf::Clear for SelectOptionCellChangesetPayload { fn clear(&mut self) { self.grid_id.clear(); self.row_id.clear(); @@ -1051,13 +1404,13 @@ impl ::protobuf::Clear for SelectOptionChangesetPayload { } } -impl ::std::fmt::Debug for SelectOptionChangesetPayload { +impl ::std::fmt::Debug for SelectOptionCellChangesetPayload { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for SelectOptionChangesetPayload { +impl ::protobuf::reflect::ProtobufValue for SelectOptionCellChangesetPayload { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1350,26 +1703,31 @@ impl ::protobuf::reflect::ProtobufValue for SelectOptionColor { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x1bselection_type_option.proto\"f\n\x16SingleSelectTypeOption\x12'\n\ - \x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdis\ - able_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"e\n\x15MultiSelectType\ - Option\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07option\ - s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"\\\n\x0cS\ - electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ - \x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\x18\x03\x20\x01(\x0e2\x12.S\ - electOptionColorR\x05color\"\xf7\x01\n\x1cSelectOptionChangesetPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ - \x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\ - \x07fieldId\x12*\n\x10insert_option_id\x18\x04\x20\x01(\tH\0R\x0einsertO\ - ptionId\x12*\n\x10delete_option_id\x18\x05\x20\x01(\tH\x01R\x0edeleteOpt\ - ionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_of_delete_option_i\ - d\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.\ - SelectOptionR\x07options\x124\n\x0eselect_options\x18\x02\x20\x03(\x0b2\ - \r.SelectOptionR\rselectOptions*y\n\x11SelectOptionColor\x12\n\n\x06Purp\ - le\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightPink\x10\x02\x12\n\n\ - \x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\n\x04Lime\x10\x05\ - \x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\x12\x08\n\x04Blue\ - \x10\x08b\x06proto3\ + \n\x1bselection_type_option.proto\x1a\x13cell_entities.proto\"f\n\x16Sin\ + gleSelectTypeOption\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOpti\ + onR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableCol\ + or\"e\n\x15MultiSelectTypeOption\x12'\n\x07options\x18\x01\x20\x03(\x0b2\ + \r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\ + \x0cdisableColor\"\\\n\x0cSelectOption\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\ + \x18\x03\x20\x01(\x0e2\x12.SelectOptionColorR\x05color\"\xfb\x01\n\x1cSe\ + lectOptionChangesetPayload\x12?\n\x0fcell_identifier\x18\x01\x20\x01(\ + \x0b2\x16.CellIdentifierPayloadR\x0ecellIdentifier\x124\n\rinsert_option\ + \x18\x02\x20\x01(\x0b2\r.SelectOptionH\0R\x0cinsertOption\x124\n\rdelete\ + _option\x18\x03\x20\x01(\x0b2\r.SelectOptionH\x01R\x0cdeleteOptionB\x16\ + \n\x14one_of_insert_optionB\x16\n\x14one_of_delete_option\"\xfb\x01\n\ + \x20SelectOptionCellChangesetPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ + \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12*\n\x10insert_optio\ + n_id\x18\x04\x20\x01(\tH\0R\x0einsertOptionId\x12*\n\x10delete_option_id\ + \x18\x05\x20\x01(\tH\x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_opti\ + on_idB\x19\n\x17one_of_delete_option_id\"t\n\x13SelectOptionContext\x12'\ + \n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\n\ + \x0eselect_options\x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOptions*\ + y\n\x11SelectOptionColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\ + \x01\x12\r\n\tLightPink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yel\ + low\x10\x04\x12\x08\n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\ + \x04Aqua\x10\x07\x12\x08\n\x04Blue\x10\x08b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto new file mode 100644 index 0000000000..d20ec4e34c --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +message CreateSelectOptionPayload { + CellIdentifierPayload cell_identifier = 1; + string option_name = 2; +} +message CellIdentifierPayload { + string grid_id = 1; + string field_id = 2; + string row_id = 3; +} +message SelectOptionName { + string name = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 6ecb36847a..cbda705483 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -6,6 +6,6 @@ enum GridNotification { DidUpdateBlock = 20; DidUpdateRow = 30; DidUpdateCell = 31; - DidUpdateFields = 40; + DidUpdateGrid = 40; DidUpdateField = 41; } 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 b423fee748..caddf2de41 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 @@ -10,10 +10,11 @@ enum GridEvent { SwitchToField = 14; DuplicateField = 15; GetEditFieldContext = 16; - CreateSelectOption = 30; - GetSelectOptions = 31; + NewSelectOption = 30; + GetSelectOptionContext = 31; + ApplySelectOptionChangeset = 32; CreateRow = 50; GetRow = 51; UpdateCell = 70; - ApplySelectOptionChangeset = 71; + ApplySelectOptionCellChangeset = 71; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/field_entities.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/field_entities.proto new file mode 100644 index 0000000000..3c670c50af --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/field_entities.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message FieldIdentifierPayload { + string field_id = 1; + string grid_id = 2; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/row_entities.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/row_entities.proto new file mode 100644 index 0000000000..d09d76e960 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/row_entities.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message RowIdentifierPayload { + string grid_id = 1; + string row_id = 3; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index 3431373504..aee0adcd5e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -1,4 +1,5 @@ syntax = "proto3"; +import "cell_entities.proto"; message SingleSelectTypeOption { repeated SelectOption options = 1; @@ -14,6 +15,11 @@ message SelectOption { SelectOptionColor color = 3; } message SelectOptionChangesetPayload { + CellIdentifierPayload cell_identifier = 1; + oneof one_of_insert_option { SelectOption insert_option = 2; }; + oneof one_of_delete_option { SelectOption delete_option = 3; }; +} +message SelectOptionCellChangesetPayload { string grid_id = 1; string row_id = 2; string field_id = 3; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index d8231dbb2e..75357a520b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -6,8 +6,8 @@ use bytes::Bytes; use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellIdentifier, CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, - GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, Row, RowMeta, RowMetaChangeset, RowOrder, + CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, + GridBlockOrder, RepeatedCell, Row, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{ diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs new file mode 100644 index 0000000000..28465d21e3 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs @@ -0,0 +1,69 @@ +use flowy_derive::ProtoBuf; +use flowy_error::ErrorCode; +use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; + +#[derive(ProtoBuf, Default)] +pub struct CreateSelectOptionPayload { + #[pb(index = 1)] + pub cell_identifier: CellIdentifierPayload, + + #[pb(index = 2)] + pub option_name: String, +} + +pub struct CreateSelectOptionParams { + pub cell_identifier: CellIdentifier, + pub option_name: String, +} + +impl TryInto for CreateSelectOptionPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; + let cell_identifier = self.cell_identifier.try_into()?; + Ok(CreateSelectOptionParams { + cell_identifier, + option_name: option_name.0, + }) + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellIdentifierPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] + pub row_id: String, +} + +pub struct CellIdentifier { + pub grid_id: String, + pub field_id: String, + pub row_id: String, +} + +impl TryInto for CellIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + Ok(CellIdentifier { + grid_id: grid_id.0, + field_id: field_id.0, + row_id: row_id.0, + }) + } +} + +#[derive(ProtoBuf, Default)] +pub struct SelectOptionName { + #[pb(index = 1)] + pub name: String, +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs new file mode 100644 index 0000000000..d2541866be --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod cell_entities; + +pub use cell_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs new file mode 100644 index 0000000000..b8ac13f773 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs @@ -0,0 +1,30 @@ +use flowy_derive::ProtoBuf; +use flowy_error::ErrorCode; +use flowy_grid_data_model::parser::NotEmptyUuid; + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldIdentifierPayload { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] + pub grid_id: String, +} + +pub struct FieldIdentifier { + pub field_id: String, + pub grid_id: String, +} + +impl TryInto for FieldIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + Ok(FieldIdentifier { + grid_id: grid_id.0, + field_id: field_id.0, + }) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 61b5889e68..89a1f05c57 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,5 +1,7 @@ mod field_builder; -mod type_options; +pub(crate) mod field_entities; +pub(crate) mod type_options; pub use field_builder::*; +pub use field_entities::*; pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 07bef42e5f..5dee72dec7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,4 +1,5 @@ use crate::impl_type_option; +use crate::services::cell::{CellIdentifier, CellIdentifierPayload}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use crate::services::util::*; @@ -16,6 +17,12 @@ use uuid::Uuid; pub const SELECTION_IDS_SEPARATOR: &str = ","; +pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync { + fn insert_option(&mut self, new_option: SelectOption); + fn delete_option(&mut self, delete_option: SelectOption); + fn option_context(&self, cell_meta: &Option) -> SelectOptionContext; +} + // Single select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SingleSelectTypeOption { @@ -27,8 +34,23 @@ pub struct SingleSelectTypeOption { } impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); -impl SingleSelectTypeOption { - pub fn select_option_context(&self, cell_meta: &Option) -> SelectOptionContext { +impl SelectOptionOperation for SingleSelectTypeOption { + fn insert_option(&mut self, new_option: SelectOption) { + if let Some(index) = self.options.iter().position(|option| option.id == new_option.id) { + self.options.remove(index); + self.options.insert(index, new_option); + } else { + self.options.insert(0, new_option); + } + } + + fn delete_option(&mut self, delete_option: SelectOption) { + if let Some(index) = self.options.iter().position(|option| option.id == delete_option.id) { + self.options.remove(index); + } + } + + fn option_context(&self, cell_meta: &Option) -> SelectOptionContext { let select_options = make_select_context_from(cell_meta, &self.options); SelectOptionContext { options: self.options.clone(), @@ -37,22 +59,6 @@ impl SingleSelectTypeOption { } } -fn make_select_context_from(cell_meta: &Option, options: &Vec) -> Vec { - match cell_meta { - None => vec![], - Some(cell_meta) => { - if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&cell_meta.data) { - select_option_ids(type_option_cell_data.data) - .into_iter() - .flat_map(|option_id| options.iter().find(|option| option.id == option_id).cloned()) - .collect() - } else { - vec![] - } - } - } -} - impl CellDataOperation for SingleSelectTypeOption { fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { @@ -78,7 +84,7 @@ impl CellDataOperation for SingleSelectTypeOption { _cell_meta: Option, ) -> Result { let changeset = changeset.into(); - let select_option_changeset: SelectOptionChangeset = serde_json::from_str(&changeset)?; + let select_option_changeset: SelectOptionCellChangeset = serde_json::from_str(&changeset)?; let new_cell_data: String; if let Some(insert_option_id) = select_option_changeset.insert_option_id { new_cell_data = insert_option_id; @@ -123,9 +129,28 @@ pub struct MultiSelectTypeOption { } impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); -impl MultiSelectTypeOption { - pub fn select_option_context(&self, cell_meta: &Option) -> SelectOptionContext { - todo!() +impl SelectOptionOperation for MultiSelectTypeOption { + fn insert_option(&mut self, new_option: SelectOption) { + if let Some(index) = self.options.iter().position(|option| option.id == new_option.id) { + self.options.remove(index); + self.options.insert(index, new_option); + } else { + self.options.insert(0, new_option); + } + } + + fn delete_option(&mut self, delete_option: SelectOption) { + if let Some(index) = self.options.iter().position(|option| option.id == delete_option.id) { + self.options.remove(index); + } + } + + fn option_context(&self, cell_meta: &Option) -> SelectOptionContext { + let select_options = make_select_context_from(cell_meta, &self.options); + SelectOptionContext { + options: self.options.clone(), + select_options, + } } } @@ -153,7 +178,7 @@ impl CellDataOperation for MultiSelectTypeOption { cell_meta: Option, ) -> Result { let changeset = changeset.into(); - let select_option_changeset: SelectOptionChangeset = serde_json::from_str(&changeset)?; + let select_option_changeset: SelectOptionCellChangeset = serde_json::from_str(&changeset)?; let new_cell_data: String; match cell_meta { None => { @@ -230,6 +255,37 @@ impl SelectOption { #[derive(Clone, Debug, Default, ProtoBuf)] pub struct SelectOptionChangesetPayload { + #[pb(index = 1)] + pub cell_identifier: CellIdentifierPayload, + + #[pb(index = 2, one_of)] + pub insert_option: Option, + + #[pb(index = 3, one_of)] + pub delete_option: Option, +} + +pub struct SelectOptionChangeset { + pub cell_identifier: CellIdentifier, + pub insert_option: Option, + pub delete_option: Option, +} + +impl TryInto for SelectOptionChangesetPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let cell_identifier = self.cell_identifier.try_into()?; + Ok(SelectOptionChangeset { + cell_identifier, + insert_option: self.insert_option, + delete_option: self.delete_option, + }) + } +} + +#[derive(Clone, Debug, Default, ProtoBuf)] +pub struct SelectOptionCellChangesetPayload { #[pb(index = 1)] pub grid_id: String, @@ -246,7 +302,7 @@ pub struct SelectOptionChangesetPayload { pub delete_option_id: Option, } -pub struct SelectOptionChangesetParams { +pub struct SelectOptionCellChangesetParams { pub grid_id: String, pub field_id: String, pub row_id: String, @@ -255,14 +311,34 @@ pub struct SelectOptionChangesetParams { } #[derive(Clone, Serialize, Deserialize)] -pub struct SelectOptionChangeset { +pub struct SelectOptionCellChangeset { pub insert_option_id: Option, pub delete_option_id: Option, } -impl std::convert::From for CellMetaChangeset { - fn from(params: SelectOptionChangesetParams) -> Self { - let changeset = SelectOptionChangeset { +impl SelectOptionCellChangeset { + pub fn from_insert(option_id: &str) -> Self { + SelectOptionCellChangeset { + insert_option_id: Some(option_id.to_string()), + delete_option_id: None, + } + } + + pub fn from_delete(option_id: &str) -> Self { + SelectOptionCellChangeset { + insert_option_id: None, + delete_option_id: Some(option_id.to_string()), + } + } + + pub fn cell_data(&self) -> String { + serde_json::to_string(self).unwrap() + } +} + +impl std::convert::From for CellMetaChangeset { + fn from(params: SelectOptionCellChangesetParams) -> Self { + let changeset = SelectOptionCellChangeset { insert_option_id: params.insert_option_id, delete_option_id: params.delete_option_id, }; @@ -276,10 +352,10 @@ impl std::convert::From for CellMetaChangeset { } } -impl TryInto for SelectOptionChangesetPayload { +impl TryInto for SelectOptionCellChangesetPayload { type Error = ErrorCode; - fn try_into(self) -> Result { + fn try_into(self) -> Result { let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; @@ -301,7 +377,7 @@ impl TryInto for SelectOptionChangesetPayload { ), }; - Ok(SelectOptionChangesetParams { + Ok(SelectOptionCellChangesetParams { grid_id: grid_id.0, row_id: row_id.0, field_id: field_id.0, @@ -340,6 +416,22 @@ impl std::default::Default for SelectOptionColor { } } +fn make_select_context_from(cell_meta: &Option, options: &Vec) -> Vec { + match cell_meta { + None => vec![], + Some(cell_meta) => { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&cell_meta.data) { + select_option_ids(type_option_cell_data.data) + .into_iter() + .flat_map(|option_id| options.iter().find(|option| option.id == option_id).cloned()) + .collect() + } else { + vec![] + } + } + } +} + #[cfg(test)] mod tests { use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption}; 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 1a184d51e9..32dfb43668 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -8,7 +8,7 @@ use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; -use flowy_sync::client_grid::{GridChangeset, GridMetaPad, TypeOptionDataDeserializer}; +use flowy_sync::client_grid::{GridChangeset, GridMetaPad, JsonDeserializer}; use flowy_sync::entities::revision::Revision; use flowy_sync::errors::CollaborateResult; use flowy_sync::util::make_delta_from_revisions; @@ -61,7 +61,7 @@ impl ClientGridEditor { let _ = self .modify(|grid| { if grid.contain_field(&field.id) { - let deserializer = TypeOptionChangesetDeserializer(field.field_type.clone()); + let deserializer = TypeOptionJsonDeserializer(field.field_type.clone()); let changeset = FieldChangesetParams { field_id: field.id, grid_id, @@ -82,7 +82,7 @@ impl ClientGridEditor { } }) .await?; - let _ = self.notify_did_update_fields().await?; + let _ = self.notify_did_update_grid().await?; Ok(()) } @@ -98,20 +98,27 @@ impl ClientGridEditor { pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let field_id = params.field_id.clone(); - let deserializer = match self.pad.read().await.get_field(params.field_id.as_str()) { + let json_deserializer = match self.pad.read().await.get_field(params.field_id.as_str()) { None => return Err(ErrorCode::FieldDoesNotExist.into()), - Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()), + Some(field_meta) => TypeOptionJsonDeserializer(field_meta.field_type.clone()), }; - let _ = self.modify(|grid| Ok(grid.update_field(params, deserializer)?)).await?; - let _ = self.notify_did_update_fields().await?; + let _ = self + .modify(|grid| Ok(grid.update_field(params, json_deserializer)?)) + .await?; + let _ = self.notify_did_update_grid().await?; let _ = self.notify_did_update_field(&field_id).await?; Ok(()) } + pub async fn replace_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { + let _ = self.modify(|pad| Ok(pad.replace_field(field_meta)?)).await?; + Ok(()) + } + pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; - let _ = self.notify_did_update_fields().await?; + let _ = self.notify_did_update_grid().await?; Ok(()) } @@ -134,28 +141,33 @@ impl ClientGridEditor { let _ = self .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) .await?; - let _ = self.notify_did_update_fields().await?; + let _ = self.notify_did_update_grid().await?; let _ = self.notify_did_update_field(field_id).await?; Ok(()) } pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.duplicate_field(field_id)?)).await?; - let _ = self.notify_did_update_fields().await?; + let _ = self.notify_did_update_grid().await?; Ok(()) } - pub async fn get_field_metas(&self, field_orders: Option>) -> FlowyResult> + pub async fn get_field_meta(&self, field_id: &str) -> Option { + let field_meta = self.pad.read().await.get_field(field_id)?.clone(); + return Some(field_meta); + } + + pub async fn get_field_metas(&self, field_ids: Option>) -> FlowyResult> where T: Into, { - if field_orders.is_none() { + if field_ids.is_none() { let field_metas = self.pad.read().await.get_field_metas(None)?; return Ok(field_metas); } let to_field_orders = |item: Vec| item.into_iter().map(|data| data.into()).collect(); - let field_orders = field_orders.map_or(vec![], to_field_orders); + let field_orders = field_ids.map_or(vec![], to_field_orders); let expected_len = field_orders.len(); let field_metas = self.pad.read().await.get_field_metas(Some(field_orders))?; if expected_len != 0 && field_metas.len() != expected_len { @@ -382,10 +394,10 @@ impl ClientGridEditor { } } - async fn notify_did_update_fields(&self) -> FlowyResult<()> { + async fn notify_did_update_grid(&self) -> FlowyResult<()> { let field_metas = self.get_field_metas::(None).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); - send_dart_notification(&self.grid_id, GridNotification::DidUpdateFields) + send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) .payload(repeated_field) .send(); Ok(()) @@ -442,12 +454,10 @@ impl RevisionCompactor for GridRevisionCompactor { } } -struct TypeOptionChangesetDeserializer(FieldType); -impl TypeOptionDataDeserializer for TypeOptionChangesetDeserializer { +struct TypeOptionJsonDeserializer(FieldType); +impl JsonDeserializer for TypeOptionJsonDeserializer { fn deserialize(&self, type_option_data: Vec) -> CollaborateResult { - // The type_option_data is serialized by protobuf. But the type_option_data should be - // serialized by utf-8. So we must transform the data here. - + // The type_option_data sent from Dart is serialized by protobuf. let builder = type_option_builder_from_bytes(type_option_data, &self.0); Ok(builder.entry().json_str()) } diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 6ae3be1dca..88e7fbec10 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 block_meta_editor; +pub mod cell; pub mod field; pub mod grid_editor; pub mod persistence; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index 9c8a04bdc3..e34c25b488 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -90,9 +90,8 @@ impl TypeOptionCellData { } } -/// The function,apply_cell_data_changeset, will apply the cell_data_changeset. -/// -/// The cell_data_changeset will be deserialized into specific data base on the FieldType. +/// The changeset will be deserialized into specific data base on the FieldType. +/// For example, it's String on FieldType::RichText, and SelectOptionChangeset on FieldType::SingleSelect pub fn apply_cell_data_changeset>( changeset: T, cell_meta: Option, diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index e2727cdf34..f9bf130e8b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -1,5 +1,6 @@ mod cell_data_operation; mod row_builder; +pub mod row_entities; mod row_loader; pub use cell_data_operation::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs new file mode 100644 index 0000000000..e88ed4ffb9 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs @@ -0,0 +1,31 @@ +use flowy_derive::ProtoBuf; +use flowy_error::ErrorCode; +use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; + +#[derive(ProtoBuf, Default)] +pub struct RowIdentifierPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 3)] + pub row_id: String, +} + +pub struct RowIdentifier { + pub grid_id: String, + pub row_id: String, +} + +impl TryInto for RowIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(RowIdentifier { + grid_id: grid_id.0, + row_id: row_id.0, + }) + } +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index c14c937f00..5ac780519b 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -59,13 +59,7 @@ async fn grid_update_field_with_empty_change() { let changeset = FieldChangesetParams { field_id: field_meta.id.clone(), grid_id: test.grid_id.clone(), - name: None, - desc: None, - field_type: None, - frozen: None, - visibility: None, - width: None, - type_option_data: None, + ..Default::default() }; let scripts = vec![ @@ -90,13 +84,10 @@ async fn grid_update_field() { let changeset = FieldChangesetParams { field_id: single_select_field.id.clone(), grid_id: test.grid_id.clone(), - name: None, - desc: None, - field_type: None, frozen: Some(true), - visibility: None, width: Some(1000), type_option_data: Some(single_select_type_option.protobuf_bytes().to_vec()), + ..Default::default() }; cloned_field.frozen = true; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index 30af0f9885..0315306871 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -103,6 +103,10 @@ pub enum ErrorCode { FieldDoesNotExist = 441, #[display(fmt = "The name of the option should not be empty")] SelectOptionNameIsEmpty = 442, + #[display(fmt = "Field not exists")] + FieldNotExists = 443, + #[display(fmt = "The operation in this field is invalid")] + FieldInvalidOperation = 444, #[display(fmt = "Field's type option data should not be empty")] TypeOptionDataIsEmpty = 450, diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index f3d669a681..5653852147 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -64,6 +64,8 @@ pub enum ErrorCode { FieldIdIsEmpty = 440, FieldDoesNotExist = 441, SelectOptionNameIsEmpty = 442, + FieldNotExists = 443, + FieldInvalidOperation = 444, TypeOptionDataIsEmpty = 450, InvalidData = 500, } @@ -114,6 +116,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 440 => ::std::option::Option::Some(ErrorCode::FieldIdIsEmpty), 441 => ::std::option::Option::Some(ErrorCode::FieldDoesNotExist), 442 => ::std::option::Option::Some(ErrorCode::SelectOptionNameIsEmpty), + 443 => ::std::option::Option::Some(ErrorCode::FieldNotExists), + 444 => ::std::option::Option::Some(ErrorCode::FieldInvalidOperation), 450 => ::std::option::Option::Some(ErrorCode::TypeOptionDataIsEmpty), 500 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None @@ -161,6 +165,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::FieldIdIsEmpty, ErrorCode::FieldDoesNotExist, ErrorCode::SelectOptionNameIsEmpty, + ErrorCode::FieldNotExists, + ErrorCode::FieldInvalidOperation, ErrorCode::TypeOptionDataIsEmpty, ErrorCode::InvalidData, ]; @@ -191,7 +197,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xb4\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xe5\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\ \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\ @@ -212,9 +218,10 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ridIdIsEmpty\x10\x9a\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\xa4\x03\x12\x11\ \n\x0cRowIdIsEmpty\x10\xae\x03\x12\x14\n\x0fOptionIdIsEmpty\x10\xaf\x03\ \x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\x12\x16\n\x11FieldDoesNotExist\ - \x10\xb9\x03\x12\x1c\n\x17SelectOptionNameIsEmpty\x10\xba\x03\x12\x1a\n\ - \x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\x10\n\x0bInvalidData\x10\xf4\ - \x03b\x06proto3\ + \x10\xb9\x03\x12\x1c\n\x17SelectOptionNameIsEmpty\x10\xba\x03\x12\x13\n\ + \x0eFieldNotExists\x10\xbb\x03\x12\x1a\n\x15FieldInvalidOperation\x10\ + \xbc\x03\x12\x1a\n\x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\x10\n\x0bInv\ + alidData\x10\xf4\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index 8ea2941815..aca3309526 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -40,6 +40,8 @@ enum ErrorCode { FieldIdIsEmpty = 440; FieldDoesNotExist = 441; SelectOptionNameIsEmpty = 442; + FieldNotExists = 443; + FieldInvalidOperation = 444; TypeOptionDataIsEmpty = 450; InvalidData = 500; } 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 56c76d1925..87a35b822d 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -55,33 +55,6 @@ impl std::convert::From for Field { } } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct FieldIdentifierPayload { - #[pb(index = 1)] - pub field_id: String, - - #[pb(index = 2)] - pub grid_id: String, -} - -pub struct FieldIdentifierParams { - pub field_id: String, - pub grid_id: String, -} - -impl TryInto for FieldIdentifierPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; - Ok(FieldIdentifierParams { - grid_id: grid_id.0, - field_id: field_id.0, - }) - } -} - #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] @@ -331,39 +304,6 @@ impl Cell { } } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct CellIdentifierPayload { - #[pb(index = 1)] - pub grid_id: String, - - #[pb(index = 2)] - pub field_id: String, - - #[pb(index = 3)] - pub row_id: String, -} - -pub struct CellIdentifier { - pub grid_id: String, - pub field_id: String, - pub row_id: String, -} - -impl TryInto for CellIdentifierPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; - let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; - Ok(CellIdentifier { - grid_id: grid_id.0, - field_id: field_id.0, - row_id: row_id.0, - }) - } -} - #[derive(Debug, Clone, Default, ProtoBuf)] pub struct CellNotificationData { #[pb(index = 1)] @@ -561,57 +501,3 @@ impl TryInto for QueryGridBlocksPayload { }) } } - -#[derive(ProtoBuf, Default)] -pub struct QueryRowPayload { - #[pb(index = 1)] - pub grid_id: String, - - #[pb(index = 3)] - pub row_id: String, -} - -pub struct QueryRowParams { - pub grid_id: String, - pub row_id: String, -} - -impl TryInto for QueryRowPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; - - Ok(QueryRowParams { - grid_id: grid_id.0, - row_id: row_id.0, - }) - } -} - -#[derive(ProtoBuf, Default)] -pub struct CreateSelectOptionPayload { - #[pb(index = 1)] - pub option_name: String, - - #[pb(index = 2)] - pub selected: bool, -} - -pub struct CreateSelectOptionParams { - pub option_name: String, - pub selected: bool, -} - -impl TryInto for CreateSelectOptionPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; - Ok(CreateSelectOptionParams { - option_name: option_name.0, - selected: self.selected, - }) - } -} 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 a64dad9191..c31a2def27 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 @@ -659,207 +659,6 @@ impl ::protobuf::reflect::ProtobufValue for Field { } } -#[derive(PartialEq,Clone,Default)] -pub struct FieldIdentifierPayload { - // message fields - pub field_id: ::std::string::String, - pub grid_id: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a FieldIdentifierPayload { - fn default() -> &'a FieldIdentifierPayload { - ::default_instance() - } -} - -impl FieldIdentifierPayload { - pub fn new() -> FieldIdentifierPayload { - ::std::default::Default::default() - } - - // string field_id = 1; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string 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()) - } -} - -impl ::protobuf::Message for FieldIdentifierPayload { - 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 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.field_id); - } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_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.field_id.is_empty() { - os.write_string(1, &self.field_id)?; - } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_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() -> FieldIdentifierPayload { - FieldIdentifierPayload::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: &FieldIdentifierPayload| { &m.field_id }, - |m: &mut FieldIdentifierPayload| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &FieldIdentifierPayload| { &m.grid_id }, - |m: &mut FieldIdentifierPayload| { &mut m.grid_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "FieldIdentifierPayload", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static FieldIdentifierPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(FieldIdentifierPayload::new) - } -} - -impl ::protobuf::Clear for FieldIdentifierPayload { - fn clear(&mut self) { - self.field_id.clear(); - self.grid_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for FieldIdentifierPayload { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldIdentifierPayload { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -3480,249 +3279,6 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } -#[derive(PartialEq,Clone,Default)] -pub struct CellIdentifierPayload { - // message fields - pub grid_id: ::std::string::String, - pub field_id: ::std::string::String, - pub row_id: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CellIdentifierPayload { - fn default() -> &'a CellIdentifierPayload { - ::default_instance() - } -} - -impl CellIdentifierPayload { - pub fn new() -> CellIdentifierPayload { - ::std::default::Default::default() - } - - // string grid_id = 1; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // string field_id = 2; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string row_id = 3; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for CellIdentifierPayload { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } - if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.field_id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.row_id); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } - if !self.field_id.is_empty() { - os.write_string(2, &self.field_id)?; - } - if !self.row_id.is_empty() { - os.write_string(3, &self.row_id)?; - } - 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() -> CellIdentifierPayload { - CellIdentifierPayload::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: &CellIdentifierPayload| { &m.grid_id }, - |m: &mut CellIdentifierPayload| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &CellIdentifierPayload| { &m.field_id }, - |m: &mut CellIdentifierPayload| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellIdentifierPayload| { &m.row_id }, - |m: &mut CellIdentifierPayload| { &mut m.row_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CellIdentifierPayload", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CellIdentifierPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CellIdentifierPayload::new) - } -} - -impl ::protobuf::Clear for CellIdentifierPayload { - fn clear(&mut self) { - self.grid_id.clear(); - self.field_id.clear(); - self.row_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CellIdentifierPayload { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct CellNotificationData { // message fields @@ -5696,401 +5252,6 @@ impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { } } -#[derive(PartialEq,Clone,Default)] -pub struct QueryRowPayload { - // message fields - pub grid_id: ::std::string::String, - pub row_id: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a QueryRowPayload { - fn default() -> &'a QueryRowPayload { - ::default_instance() - } -} - -impl QueryRowPayload { - pub fn new() -> QueryRowPayload { - ::std::default::Default::default() - } - - // string grid_id = 1; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // string row_id = 3; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for QueryRowPayload { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.row_id); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } - if !self.row_id.is_empty() { - os.write_string(3, &self.row_id)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> QueryRowPayload { - QueryRowPayload::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &QueryRowPayload| { &m.grid_id }, - |m: &mut QueryRowPayload| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &QueryRowPayload| { &m.row_id }, - |m: &mut QueryRowPayload| { &mut m.row_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "QueryRowPayload", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static QueryRowPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(QueryRowPayload::new) - } -} - -impl ::protobuf::Clear for QueryRowPayload { - fn clear(&mut self) { - self.grid_id.clear(); - self.row_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for QueryRowPayload { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct CreateSelectOptionPayload { - // message fields - pub option_name: ::std::string::String, - pub selected: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CreateSelectOptionPayload { - fn default() -> &'a CreateSelectOptionPayload { - ::default_instance() - } -} - -impl CreateSelectOptionPayload { - pub fn new() -> CreateSelectOptionPayload { - ::std::default::Default::default() - } - - // string option_name = 1; - - - pub fn get_option_name(&self) -> &str { - &self.option_name - } - pub fn clear_option_name(&mut self) { - self.option_name.clear(); - } - - // Param is passed by value, moved - pub fn set_option_name(&mut self, v: ::std::string::String) { - self.option_name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_option_name(&mut self) -> &mut ::std::string::String { - &mut self.option_name - } - - // Take field - pub fn take_option_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.option_name, ::std::string::String::new()) - } - - // bool selected = 2; - - - pub fn get_selected(&self) -> bool { - self.selected - } - pub fn clear_selected(&mut self) { - self.selected = false; - } - - // Param is passed by value, moved - pub fn set_selected(&mut self, v: bool) { - self.selected = v; - } -} - -impl ::protobuf::Message for CreateSelectOptionPayload { - 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.option_name)?; - }, - 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.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.option_name.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.option_name); - } - if self.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.option_name.is_empty() { - os.write_string(1, &self.option_name)?; - } - if self.selected != false { - os.write_bool(2, self.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() -> CreateSelectOptionPayload { - CreateSelectOptionPayload::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>( - "option_name", - |m: &CreateSelectOptionPayload| { &m.option_name }, - |m: &mut CreateSelectOptionPayload| { &mut m.option_name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "selected", - |m: &CreateSelectOptionPayload| { &m.selected }, - |m: &mut CreateSelectOptionPayload| { &mut m.selected }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CreateSelectOptionPayload", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CreateSelectOptionPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CreateSelectOptionPayload::new) - } -} - -impl ::protobuf::Clear for CreateSelectOptionPayload { - fn clear(&mut self) { - self.option_name.clear(); - self.selected = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CreateSelectOptionPayload { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CreateSelectOptionPayload { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ \n\ngrid.proto\x1a\nmeta.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ @@ -6100,61 +5261,53 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\ \x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\ \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ - \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"L\n\x16FieldIdentifi\ - erPayload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\ - \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08\ - field_id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldConte\ - xtPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\ - \x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\ - \x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\ - \n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridI\ - d\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_typ\ - e\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\ - \x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\ - \x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\ - \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFiel\ - dOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\ - \n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\ - \n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\ - \x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ - Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ - lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ - \x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05item\ - s\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\ - \x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\ - \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\ - \x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\ - \x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07\ - content\"b\n\x15CellIdentifierPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ - \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"\x8f\x01\n\x14CellNot\ - ificationData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\ - \n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\ - \x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\ - \x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05i\ - tems\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\ - \x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\ - \n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\ - \x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\ - \x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\ - \n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gri\ - dId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\ - \x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0es\ - tart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_st\ - art_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.Repe\ - atedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\ - \x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrders\"A\n\x0fQueryRowPayloa\ - d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ - \x18\x03\x20\x01(\tR\x05rowId\"X\n\x19CreateSelectOptionPayload\x12\x1f\ - \n\x0boption_name\x18\x01\x20\x01(\tR\noptionName\x12\x1a\n\x08selected\ - \x18\x02\x20\x01(\x08R\x08selectedb\x06proto3\ + \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEdit\ + FieldContextPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x12\x1b\n\x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_t\ + ype\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field\ + _id\"q\n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\n\ + field_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFie\ + ldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngri\ + d_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_optio\ + n_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ + \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ + edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ + ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ + t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ + \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ + \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ + \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ + .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ + \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ + items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\ + \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ + \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ + \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ + \x07content\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07\ + fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07co\ + ntent\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\ + \x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05i\ + tems\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04\ + name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"\ + #\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\ + \x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13on\ + e_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\ + \x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\ + \x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\ + \x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cst\ + artFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\ + \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\ + \x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16Qu\ + eryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblo\ + ckOrdersb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs index d011b76000..e2e2c75a6e 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs @@ -4,5 +4,8 @@ mod grid; pub use grid::*; +mod type_option; +pub use type_option::*; + mod meta; pub use meta::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs new file mode 100644 index 0000000000..1cad4b09e8 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs @@ -0,0 +1,978 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `type_option.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 SelectOption { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub color: SelectOptionColor, + // 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()) + } + + // .SelectOptionColor color = 3; + + + pub fn get_color(&self) -> SelectOptionColor { + self.color + } + pub fn clear_color(&mut self) { + self.color = SelectOptionColor::Purple; + } + + // Param is passed by value, moved + pub fn set_color(&mut self, v: SelectOptionColor) { + self.color = v; + } +} + +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_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.color, 3, &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.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 != SelectOptionColor::Purple { + my_size += ::protobuf::rt::enum_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 != SelectOptionColor::Purple { + os.write_enum(3, ::protobuf::ProtobufEnum::value(&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::ProtobufTypeEnum>( + "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 = SelectOptionColor::Purple; + 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 SelectOptionCellChangesetPayload { + // message fields + pub grid_id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_insert_option_id: ::std::option::Option, + pub one_of_delete_option_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOptionCellChangesetPayload { + fn default() -> &'a SelectOptionCellChangesetPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id { + insert_option_id(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id { + delete_option_id(::std::string::String), +} + +impl SelectOptionCellChangesetPayload { + pub fn new() -> SelectOptionCellChangesetPayload { + ::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()) + } + + // 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 insert_option_id = 4; + + + pub fn get_insert_option_id(&self) -> &str { + match self.one_of_insert_option_id { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v)) => v, + _ => "", + } + } + pub fn clear_insert_option_id(&mut self) { + self.one_of_insert_option_id = ::std::option::Option::None; + } + + pub fn has_insert_option_id(&self) -> bool { + match self.one_of_insert_option_id { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_insert_option_id(&mut self, v: ::std::string::String) { + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_insert_option_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(_)) = self.one_of_insert_option_id { + } else { + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(::std::string::String::new())); + } + match self.one_of_insert_option_id { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_insert_option_id(&mut self) -> ::std::string::String { + if self.has_insert_option_id() { + match self.one_of_insert_option_id.take() { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // string delete_option_id = 5; + + + pub fn get_delete_option_id(&self) -> &str { + match self.one_of_delete_option_id { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v)) => v, + _ => "", + } + } + pub fn clear_delete_option_id(&mut self) { + self.one_of_delete_option_id = ::std::option::Option::None; + } + + pub fn has_delete_option_id(&self) -> bool { + match self.one_of_delete_option_id { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_delete_option_id(&mut self, v: ::std::string::String) { + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_delete_option_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(_)) = self.one_of_delete_option_id { + } else { + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(::std::string::String::new())); + } + match self.one_of_delete_option_id { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_delete_option_id(&mut self) -> ::std::string::String { + if self.has_delete_option_id() { + match self.one_of_delete_option_id.take() { + ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for SelectOptionCellChangesetPayload { + 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 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !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 ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { + match v { + &SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { + my_size += ::protobuf::rt::string_size(4, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { + match v { + &SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { + my_size += ::protobuf::rt::string_size(5, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.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 ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { + match v { + &SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { + os.write_string(4, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { + match v { + &SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { + os.write_string(5, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SelectOptionCellChangesetPayload { + SelectOptionCellChangesetPayload::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: &SelectOptionCellChangesetPayload| { &m.grid_id }, + |m: &mut SelectOptionCellChangesetPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &SelectOptionCellChangesetPayload| { &m.row_id }, + |m: &mut SelectOptionCellChangesetPayload| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &SelectOptionCellChangesetPayload| { &m.field_id }, + |m: &mut SelectOptionCellChangesetPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "insert_option_id", + SelectOptionCellChangesetPayload::has_insert_option_id, + SelectOptionCellChangesetPayload::get_insert_option_id, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "delete_option_id", + SelectOptionCellChangesetPayload::has_delete_option_id, + SelectOptionCellChangesetPayload::get_delete_option_id, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionCellChangesetPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOptionCellChangesetPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionCellChangesetPayload::new) + } +} + +impl ::protobuf::Clear for SelectOptionCellChangesetPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.row_id.clear(); + self.field_id.clear(); + self.one_of_insert_option_id = ::std::option::Option::None; + self.one_of_delete_option_id = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOptionCellChangesetPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionCellChangesetPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SelectOptionContext { + // message fields + pub options: ::protobuf::RepeatedField, + pub select_options: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOptionContext { + fn default() -> &'a SelectOptionContext { + ::default_instance() + } +} + +impl SelectOptionContext { + pub fn new() -> SelectOptionContext { + ::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()) + } + + // repeated .SelectOption select_options = 2; + + + pub fn get_select_options(&self) -> &[SelectOption] { + &self.select_options + } + pub fn clear_select_options(&mut self) { + self.select_options.clear(); + } + + // Param is passed by value, moved + pub fn set_select_options(&mut self, v: ::protobuf::RepeatedField) { + self.select_options = v; + } + + // Mutable pointer to the field. + pub fn mut_select_options(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.select_options + } + + // Take field + pub fn take_select_options(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.select_options, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for SelectOptionContext { + fn is_initialized(&self) -> bool { + for v in &self.options { + if !v.is_initialized() { + return false; + } + }; + for v in &self.select_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 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.select_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; + for value in &self.options { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.select_options { + 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.options { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.select_options { + 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() -> SelectOptionContext { + SelectOptionContext::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: &SelectOptionContext| { &m.options }, + |m: &mut SelectOptionContext| { &mut m.options }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "select_options", + |m: &SelectOptionContext| { &m.select_options }, + |m: &mut SelectOptionContext| { &mut m.select_options }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOptionContext", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOptionContext { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOptionContext::new) + } +} + +impl ::protobuf::Clear for SelectOptionContext { + fn clear(&mut self) { + self.options.clear(); + self.select_options.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOptionContext { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionContext { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum SelectOptionColor { + Purple = 0, + Pink = 1, + LightPink = 2, + Orange = 3, + Yellow = 4, + Lime = 5, + Green = 6, + Aqua = 7, + Blue = 8, +} + +impl ::protobuf::ProtobufEnum for SelectOptionColor { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(SelectOptionColor::Purple), + 1 => ::std::option::Option::Some(SelectOptionColor::Pink), + 2 => ::std::option::Option::Some(SelectOptionColor::LightPink), + 3 => ::std::option::Option::Some(SelectOptionColor::Orange), + 4 => ::std::option::Option::Some(SelectOptionColor::Yellow), + 5 => ::std::option::Option::Some(SelectOptionColor::Lime), + 6 => ::std::option::Option::Some(SelectOptionColor::Green), + 7 => ::std::option::Option::Some(SelectOptionColor::Aqua), + 8 => ::std::option::Option::Some(SelectOptionColor::Blue), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [SelectOptionColor] = &[ + SelectOptionColor::Purple, + SelectOptionColor::Pink, + SelectOptionColor::LightPink, + SelectOptionColor::Orange, + SelectOptionColor::Yellow, + SelectOptionColor::Lime, + SelectOptionColor::Green, + SelectOptionColor::Aqua, + SelectOptionColor::Blue, + ]; + 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::("SelectOptionColor", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for SelectOptionColor { +} + +impl ::std::default::Default for SelectOptionColor { + fn default() -> Self { + SelectOptionColor::Purple + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOptionColor { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x11type_option.proto\"\\\n\x0cSelectOption\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12(\n\ + \x05color\x18\x03\x20\x01(\x0e2\x12.SelectOptionColorR\x05color\"\xfb\ + \x01\n\x20SelectOptionCellChangesetPayload\x12\x17\n\x07grid_id\x18\x01\ + \x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\ + \x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12*\n\x10insert_o\ + ption_id\x18\x04\x20\x01(\tH\0R\x0einsertOptionId\x12*\n\x10delete_optio\ + n_id\x18\x05\x20\x01(\tH\x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_\ + option_idB\x19\n\x17one_of_delete_option_id\"t\n\x13SelectOptionContext\ + \x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\ + \n\x0eselect_options\x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOption\ + s*y\n\x11SelectOptionColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\ + \x01\x12\r\n\tLightPink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yel\ + low\x10\x04\x12\x08\n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\ + \x04Aqua\x10\x07\x12\x08\n\x04Blue\x10\x08b\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/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 6be5bf1a64..c1166a3ae1 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 @@ -15,10 +15,6 @@ message Field { bool visibility = 6; int32 width = 7; } -message FieldIdentifierPayload { - string field_id = 1; - string grid_id = 2; -} message FieldOrder { string field_id = 1; } @@ -70,11 +66,6 @@ message Cell { string field_id = 1; string content = 2; } -message CellIdentifierPayload { - string grid_id = 1; - string field_id = 2; - string row_id = 3; -} message CellNotificationData { string grid_id = 1; string field_id = 2; @@ -111,11 +102,3 @@ message QueryGridBlocksPayload { string grid_id = 1; repeated GridBlockOrder block_orders = 2; } -message QueryRowPayload { - string grid_id = 1; - string row_id = 3; -} -message CreateSelectOptionPayload { - string option_name = 1; - bool selected = 2; -} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto new file mode 100644 index 0000000000..5f375f93aa --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +message SelectOption { + string id = 1; + string name = 2; + SelectOptionColor color = 3; +} +message SelectOptionCellChangesetPayload { + string grid_id = 1; + string row_id = 2; + string field_id = 3; + oneof one_of_insert_option_id { string insert_option_id = 4; }; + oneof one_of_delete_option_id { string delete_option_id = 5; }; +} +message SelectOptionContext { + repeated SelectOption options = 1; + repeated SelectOption select_options = 2; +} +enum SelectOptionColor { + Purple = 0; + Pink = 1; + LightPink = 2; + Orange = 3; + Yellow = 4; + Lime = 5; + Green = 6; + Aqua = 7; + Blue = 8; +} diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 2d2e9888f6..8329d9cc9c 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -20,7 +20,7 @@ pub struct GridMetaPad { pub(crate) delta: GridMetaDelta, } -pub trait TypeOptionDataDeserializer { +pub trait JsonDeserializer { fn deserialize(&self, type_option_data: Vec) -> CollaborateResult; } @@ -47,47 +47,55 @@ impl GridMetaPad { new_field_meta: FieldMeta, start_field_id: Option, ) -> CollaborateResult> { - self.modify_grid(|grid| { + self.modify_grid(|grid_meta| { // Check if the field exists or not - if grid.fields.iter().any(|field_meta| field_meta.id == new_field_meta.id) { + if grid_meta + .fields + .iter() + .any(|field_meta| field_meta.id == new_field_meta.id) + { tracing::error!("Duplicate grid field"); return Ok(None); } let insert_index = match start_field_id { None => None, - Some(start_field_id) => grid.fields.iter().position(|field| field.id == start_field_id), + Some(start_field_id) => grid_meta.fields.iter().position(|field| field.id == start_field_id), }; match insert_index { - None => grid.fields.push(new_field_meta), - Some(index) => grid.fields.insert(index, new_field_meta), + None => grid_meta.fields.push(new_field_meta), + Some(index) => grid_meta.fields.insert(index, new_field_meta), } Ok(Some(())) }) } pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { - self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { - None => Ok(None), - Some(index) => { - grid.fields.remove(index); - Ok(Some(())) - } - }) + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + grid_meta.fields.remove(index); + Ok(Some(())) + } + }, + ) } pub fn duplicate_field(&mut self, field_id: &str) -> CollaborateResult> { - self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { - None => Ok(None), - Some(index) => { - let mut duplicate_field_meta = grid.fields[index].clone(); - duplicate_field_meta.id = uuid(); - duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); - grid.fields.insert(index + 1, duplicate_field_meta); - Ok(Some(())) - } - }) + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + let mut duplicate_field_meta = grid_meta.fields[index].clone(); + duplicate_field_meta.id = uuid(); + duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); + grid_meta.fields.insert(index + 1, duplicate_field_meta); + Ok(Some(())) + } + }, + ) } pub fn switch_to_field( @@ -99,9 +107,9 @@ impl GridMetaPad { where B: FnOnce(&FieldType) -> String, { - self.modify_grid(|grid| { + self.modify_grid(|grid_meta| { // - match grid.fields.iter_mut().find(|field_meta| field_meta.id == field_id) { + match grid_meta.fields.iter_mut().find(|field_meta| field_meta.id == field_id) { None => { tracing::warn!("Can not find the field with id: {}", field_id); Ok(None) @@ -119,7 +127,7 @@ impl GridMetaPad { }) } - pub fn update_field( + pub fn update_field( &mut self, changeset: FieldChangesetParams, deserializer: T, @@ -178,6 +186,19 @@ impl GridMetaPad { self.grid_meta.fields.iter().find(|field| field.id == field_id) } + pub fn replace_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_meta.id) { + None => Ok(None), + Some(index) => { + grid_meta.fields.remove(index); + grid_meta.fields.insert(index, field_meta); + Ok(Some(())) + } + }, + ) + } + pub fn contain_field(&self, field_id: &str) -> bool { self.grid_meta.fields.iter().any(|field| field.id == field_id) } @@ -213,13 +234,13 @@ impl GridMetaPad { } pub fn create_block_meta(&mut self, block: GridBlockMeta) -> CollaborateResult> { - self.modify_grid(|grid| { - if grid.block_metas.iter().any(|b| b.block_id == block.block_id) { + self.modify_grid(|grid_meta| { + if grid_meta.block_metas.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { - match grid.block_metas.last() { - None => grid.block_metas.push(block), + match grid_meta.block_metas.last() { + None => grid_meta.block_metas.push(block), Some(last_block) => { if last_block.start_row_index > block.start_row_index && last_block.len() > block.start_row_index @@ -227,7 +248,7 @@ impl GridMetaPad { let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string(); return Err(CollaborateError::internal().context(msg)) } - grid.block_metas.push(block); + grid_meta.block_metas.push(block); } } Ok(Some(())) @@ -299,28 +320,34 @@ impl GridMetaPad { where F: FnOnce(&mut GridBlockMeta) -> CollaborateResult>, { - self.modify_grid( - |grid| match grid.block_metas.iter().position(|block| block.block_id == block_id) { + self.modify_grid(|grid_meta| { + match grid_meta + .block_metas + .iter() + .position(|block| block.block_id == block_id) + { None => { tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); Ok(None) } - Some(index) => f(&mut grid.block_metas[index]), - }, - ) + Some(index) => f(&mut grid_meta.block_metas[index]), + } + }) } pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut FieldMeta) -> CollaborateResult>, { - self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { - None => { - tracing::warn!("[GridMetaPad]: Can't find any field with id: {}", field_id); - Ok(None) - } - Some(index) => f(&mut grid.fields[index]), - }) + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any field with id: {}", field_id); + Ok(None) + } + Some(index) => f(&mut grid_meta.fields[index]), + }, + ) } } From a3770a699ccb56329cbaba2618bddeb9c0aff806 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 15:34:00 +0800 Subject: [PATCH 101/179] fix: unit test errors --- .../lib/user/presentation/splash_screen.dart | 2 +- .../application/home/home_listen_bloc.dart | 2 +- .../cell/selection_cell/selection_cell.dart | 19 +- .../flowy-folder-data-model/errors.pb.dart | 11 - .../errors.pbenum.dart | 56 - .../errors.pbjson.dart | 36 - .../errors.pbserver.dart | 9 - .../flowy-grid-data-model/protobuf.dart | 2 +- frontend/rust-lib/flowy-grid/src/macros.rs | 2 +- frontend/rust-lib/flowy-grid/src/manager.rs | 10 + .../src/services/block_meta_editor.rs | 255 +---- .../src/services/block_meta_manager.rs | 248 +++++ .../type_options/checkbox_type_option.rs | 30 +- .../field/type_options/date_type_option.rs | 4 +- .../field/type_options/number_type_option.rs | 2 +- .../type_options/selection_type_option.rs | 109 +- .../field/type_options/text_type_option.rs | 22 +- .../flowy-grid/src/services/grid_editor.rs | 6 +- .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../src/services/row/row_builder.rs | 17 + .../src/services/row/row_entities.rs | 2 +- frontend/rust-lib/flowy-grid/src/util.rs | 13 +- .../flowy-grid/tests/grid/grid_test.rs | 87 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 19 +- .../src/entities/grid.rs | 3 +- .../src/entities/meta.rs | 2 +- .../src/protobuf/model/mod.rs | 3 - .../src/protobuf/model/type_option.rs | 978 ------------------ .../src/protobuf/proto/type_option.proto | 29 - 29 files changed, 468 insertions(+), 1511 deletions(-) delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs delete mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs delete mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto diff --git a/frontend/app_flowy/lib/user/presentation/splash_screen.dart b/frontend/app_flowy/lib/user/presentation/splash_screen.dart index 5fe302abd0..dd8fdcd180 100644 --- a/frontend/app_flowy/lib/user/presentation/splash_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/splash_screen.dart @@ -4,7 +4,7 @@ import 'package:app_flowy/user/domain/auth_state.dart'; import 'package:app_flowy/user/presentation/router.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/error-code/error_code.pbenum.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart b/frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart index f3da1af678..0ebb572e17 100644 --- a/frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/user/application/user_listener.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/error-code/error_code.pbenum.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 2187325c95..3e6f5b1649 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -72,13 +72,28 @@ class _MultiSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellData); + _cellBloc = getIt(param1: widget.cellData)..add(const SelectionCellEvent.initial()); super.initState(); } @override Widget build(BuildContext context) { - return Container(); + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + final children = state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList(); + return SizedBox.expand( + child: InkWell( + onTap: () { + SelectOptionEditor.show(context, state.cellData, state.options, state.selectedOptions); + }, + child: Row(children: children), + ), + ); + }, + ), + ); } @override diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pb.dart deleted file mode 100644 index f2ec97799a..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pb.dart +++ /dev/null @@ -1,11 +0,0 @@ -/// -// Generated code. Do not modify. -// source: errors.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 'errors.pbenum.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbenum.dart deleted file mode 100644 index 52eb16349e..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbenum.dart +++ /dev/null @@ -1,56 +0,0 @@ -/// -// Generated code. Do not modify. -// source: errors.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 ErrorCode extends $pb.ProtobufEnum { - static const ErrorCode WorkspaceNameInvalid = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameInvalid'); - static const ErrorCode WorkspaceIdInvalid = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceIdInvalid'); - static const ErrorCode AppColorStyleInvalid = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid'); - static const ErrorCode WorkspaceDescTooLong = ErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDescTooLong'); - static const ErrorCode WorkspaceNameTooLong = ErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameTooLong'); - static const ErrorCode AppIdInvalid = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppIdInvalid'); - static const ErrorCode AppNameInvalid = ErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppNameInvalid'); - static const ErrorCode ViewNameInvalid = ErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewNameInvalid'); - static const ErrorCode ViewThumbnailInvalid = ErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewThumbnailInvalid'); - static const ErrorCode ViewIdInvalid = ErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewIdInvalid'); - static const ErrorCode ViewDescTooLong = ErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDescTooLong'); - static const ErrorCode ViewDataInvalid = ErrorCode._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDataInvalid'); - static const ErrorCode ViewNameTooLong = ErrorCode._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewNameTooLong'); - static const ErrorCode UserUnauthorized = ErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized'); - static const ErrorCode WsConnectError = ErrorCode._(200, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WsConnectError'); - static const ErrorCode InternalError = ErrorCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InternalError'); - static const ErrorCode RecordNotFound = ErrorCode._(1001, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RecordNotFound'); - - static const $core.List values = [ - WorkspaceNameInvalid, - WorkspaceIdInvalid, - AppColorStyleInvalid, - WorkspaceDescTooLong, - WorkspaceNameTooLong, - AppIdInvalid, - AppNameInvalid, - ViewNameInvalid, - ViewThumbnailInvalid, - ViewIdInvalid, - ViewDescTooLong, - ViewDataInvalid, - ViewNameTooLong, - UserUnauthorized, - WsConnectError, - InternalError, - RecordNotFound, - ]; - - static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values); - static ErrorCode? valueOf($core.int value) => _byValue[value]; - - const ErrorCode._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbjson.dart deleted file mode 100644 index a829c0ed5d..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbjson.dart +++ /dev/null @@ -1,36 +0,0 @@ -/// -// Generated code. Do not modify. -// source: errors.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 errorCodeDescriptor instead') -const ErrorCode$json = const { - '1': 'ErrorCode', - '2': const [ - const {'1': 'WorkspaceNameInvalid', '2': 0}, - const {'1': 'WorkspaceIdInvalid', '2': 1}, - const {'1': 'AppColorStyleInvalid', '2': 2}, - const {'1': 'WorkspaceDescTooLong', '2': 3}, - const {'1': 'WorkspaceNameTooLong', '2': 4}, - const {'1': 'AppIdInvalid', '2': 10}, - const {'1': 'AppNameInvalid', '2': 11}, - const {'1': 'ViewNameInvalid', '2': 20}, - const {'1': 'ViewThumbnailInvalid', '2': 21}, - const {'1': 'ViewIdInvalid', '2': 22}, - const {'1': 'ViewDescTooLong', '2': 23}, - const {'1': 'ViewDataInvalid', '2': 24}, - const {'1': 'ViewNameTooLong', '2': 25}, - const {'1': 'UserUnauthorized', '2': 100}, - const {'1': 'WsConnectError', '2': 200}, - const {'1': 'InternalError', '2': 1000}, - const {'1': 'RecordNotFound', '2': 1001}, - ], -}; - -/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQABIWChJXb3Jrc3BhY2VJZEludmFsaWQQARIYChRBcHBDb2xvclN0eWxlSW52YWxpZBACEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEAMSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQBBIQCgxBcHBJZEludmFsaWQQChISCg5BcHBOYW1lSW52YWxpZBALEhMKD1ZpZXdOYW1lSW52YWxpZBAUEhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEBUSEQoNVmlld0lkSW52YWxpZBAWEhMKD1ZpZXdEZXNjVG9vTG9uZxAXEhMKD1ZpZXdEYXRhSW52YWxpZBAYEhMKD1ZpZXdOYW1lVG9vTG9uZxAZEhQKEFVzZXJVbmF1dGhvcml6ZWQQZBITCg5Xc0Nvbm5lY3RFcnJvchDIARISCg1JbnRlcm5hbEVycm9yEOgHEhMKDlJlY29yZE5vdEZvdW5kEOkH'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbserver.dart deleted file mode 100644 index 18b02b9216..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/errors.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: errors.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 'errors.pb.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart index 6cedb363ef..2c253e0494 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart @@ -1,3 +1,3 @@ -// Auto-generated, do not edit +// Auto-generated, do not edit export './grid.pb.dart'; export './meta.pb.dart'; diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 4a4994729c..e635e63790 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -52,7 +52,7 @@ macro_rules! impl_type_option { match serde_json::to_string(&self) { Ok(s) => s, Err(e) => { - tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); + tracing::error!("Field type data serialize to json fail, error: {:?}", e); serde_json::to_string(&$target::default()).unwrap() } } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index d82b2950da..d35ad334c9 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -23,6 +23,7 @@ pub struct GridManager { editor_map: Arc, grid_user: Arc, block_index_persistence: Arc, + #[allow(dead_code)] kv_persistence: Arc, } @@ -181,12 +182,21 @@ pub async fn make_grid_view_data( block_metas: vec![build_context.block_metas], }; + // Create grid let grid_meta_delta = make_grid_delta(&grid_meta); let grid_delta_data = grid_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); let _ = grid_manager.create_grid(view_id, repeated_revision).await?; + // Indexing the block's rows + build_context.block_meta_data.row_metas.iter().for_each(|row| { + let _ = grid_manager + .block_index_persistence + .insert_or_update(&row.block_id, &row.id); + }); + + // Create grid's block let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 75357a520b..8518a70fb0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -1,263 +1,16 @@ -use crate::dart_notification::{send_dart_notification, GridNotification}; -use crate::manager::GridUser; -use crate::services::persistence::block_index::BlockIndexPersistence; -use crate::services::row::{make_block_row_ids, make_cell_by_field_id, make_rows_from_row_metas, GridBlockSnapshot}; use bytes::Bytes; -use dashmap::DashMap; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, - GridBlockOrder, RepeatedCell, Row, RowMeta, RowMetaChangeset, RowOrder, -}; -use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; -use flowy_revision::{ - RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, -}; +use flowy_grid_data_model::entities::{CellMeta, RowMeta, RowMetaChangeset, RowOrder}; +use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_sync::entities::revision::Revision; use flowy_sync::util::make_delta_from_revisions; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; -use std::collections::HashMap; + use std::sync::Arc; use tokio::sync::RwLock; -pub(crate) struct GridBlockMetaEditorManager { - grid_id: String, - user: Arc, - editor_map: DashMap>, - persistence: Arc, -} - -impl GridBlockMetaEditorManager { - pub(crate) async fn new( - grid_id: &str, - user: &Arc, - blocks: Vec, - persistence: Arc, - ) -> FlowyResult { - let editor_map = make_block_meta_editor_map(user, blocks).await?; - let user = user.clone(); - let grid_id = grid_id.to_owned(); - let manager = Self { - grid_id, - user, - editor_map, - persistence, - }; - Ok(manager) - } - - // #[tracing::instrument(level = "trace", skip(self))] - pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { - debug_assert!(!block_id.is_empty()); - match self.editor_map.get(block_id) { - None => { - tracing::error!("The is a fatal error, block is not exist"); - let editor = Arc::new(make_block_meta_editor(&self.user, block_id).await?); - self.editor_map.insert(block_id.to_owned(), editor.clone()); - Ok(editor) - } - Some(editor) => Ok(editor.clone()), - } - } - - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { - let block_id = self.persistence.get_block_id(row_id)?; - Ok(self.get_editor(&block_id).await?) - } - - pub(crate) async fn create_row( - &self, - block_id: &str, - row_meta: RowMeta, - start_row_id: Option, - ) -> FlowyResult { - let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?; - let editor = self.get_editor(&row_meta.block_id).await?; - let row_count = editor.create_row(row_meta, start_row_id).await?; - self.notify_block_did_update_row(block_id).await?; - Ok(row_count) - } - - pub(crate) async fn insert_row( - &self, - rows_by_block_id: HashMap>, - ) -> FlowyResult> { - let mut changesets = vec![]; - for (block_id, row_metas) in rows_by_block_id { - let editor = self.get_editor(&block_id).await?; - let mut row_count = 0; - for row in &row_metas { - let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; - row_count = editor.create_row(row.clone(), None).await?; - } - changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); - let _ = self.notify_block_did_update_row(&block_id).await?; - } - - Ok(changesets) - } - - pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { - let mut changesets = vec![]; - for block_row_ids in make_block_row_ids(&row_orders) { - let editor = self.get_editor(&block_row_ids.block_id).await?; - let row_count = editor.delete_rows(block_row_ids.row_ids).await?; - - let changeset = GridBlockMetaChangeset::from_row_count(&block_row_ids.block_id, row_count); - changesets.push(changeset); - } - - Ok(changesets) - } - - pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { - let editor = self.get_editor_from_row_id(&changeset.row_id).await?; - let _ = editor.update_row(changeset.clone()).await?; - let _ = self.notify_block_did_update_row(&editor.block_id).await?; - Ok(()) - } - - pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { - let row_id = changeset.row_id.clone(); - let editor = self.get_editor_from_row_id(&row_id).await?; - let row_changeset: RowMetaChangeset = changeset.clone().into(); - let _ = editor.update_row(row_changeset).await?; - - let cell_notification_data = CellNotificationData { - grid_id: changeset.grid_id, - field_id: changeset.field_id, - row_id: changeset.row_id, - content: changeset.data, - }; - self.notify_did_update_cell(cell_notification_data).await?; - Ok(()) - } - - pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult>> { - let editor = self.get_editor_from_row_id(row_id).await?; - let row_ids = vec![row_id.to_owned()]; - let mut row_metas = editor.get_row_metas(Some(row_ids)).await?; - if row_metas.is_empty() { - Ok(None) - } else { - Ok(row_metas.pop()) - } - } - - pub(crate) async fn make_block_snapshots(&self, block_ids: Vec) -> FlowyResult> { - let mut snapshots = vec![]; - for block_id in block_ids { - let editor = self.get_editor(&block_id).await?; - let row_metas = editor.get_row_metas(None).await?; - - row_metas.iter().for_each(|row| { - let _ = self.persistence.insert_or_update(&row.block_id, &row.id); - }); - - snapshots.push(GridBlockSnapshot { block_id, row_metas }); - } - Ok(snapshots) - } - - // Optimization: Using the shared memory(Arc, Cow,etc.) to reduce memory usage. - #[allow(dead_code)] - pub async fn get_cell_metas( - &self, - block_ids: Vec, - field_id: &str, - row_ids: Option>, - ) -> FlowyResult> { - let mut block_cell_metas = vec![]; - for block_id in block_ids { - let editor = self.get_editor(&block_id).await?; - let cell_metas = editor.get_cell_metas(field_id, &row_ids).await?; - block_cell_metas.extend(cell_metas); - } - Ok(block_cell_metas) - } - - async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { - let block_order: GridBlockOrder = block_id.into(); - send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock) - .payload(block_order) - .send(); - Ok(()) - } - - async fn notify_did_update_cell(&self, data: CellNotificationData) -> FlowyResult<()> { - let id = format!("{}:{}", data.row_id, data.field_id); - send_dart_notification(&id, GridNotification::DidUpdateCell) - .payload(data) - .send(); - Ok(()) - } - - async fn notify_did_update_row(&self, row_id: &str, field_metas: &[FieldMeta]) -> FlowyResult<()> { - match self.get_row_meta(row_id).await? { - None => {} - Some(row_meta) => { - let row_metas = vec![row_meta]; - if let Some(row) = make_rows_from_row_metas(&field_metas, &row_metas).pop() { - send_dart_notification(row_id, GridNotification::DidUpdateRow) - .payload(row) - .send(); - } - } - } - Ok(()) - - // - // let field_meta_map = field_metas - // .iter() - // .map(|field_meta| (&field_meta.id, field_meta)) - // .collect::>(); - // - // let mut cells = vec![]; - // changeset - // .cell_by_field_id - // .into_iter() - // .for_each( - // |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) { - // None => {} - // Some((_, cell)) => cells.push(cell), - // }, - // ); - // - // if !cells.is_empty() { - // send_dart_notification(&changeset.row_id, GridNotification::DidUpdateRow) - // .payload(RepeatedCell::from(cells)) - // .send(); - // } - // Ok(()) - } -} - -async fn make_block_meta_editor_map( - user: &Arc, - blocks: Vec, -) -> FlowyResult>> { - let editor_map = DashMap::new(); - for block in blocks { - let editor = make_block_meta_editor(user, &block.block_id).await?; - editor_map.insert(block.block_id, Arc::new(editor)); - } - - Ok(editor_map) -} - -async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { - let token = user.token()?; - let user_id = user.user_id()?; - let pool = user.db_pool()?; - - let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache)); - let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence); - ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await -} - pub struct ClientGridBlockMetaEditor { user_id: String, pub block_id: String, @@ -288,7 +41,7 @@ impl ClientGridBlockMetaEditor { }) } - async fn create_row(&self, row: RowMeta, start_row_id: Option) -> FlowyResult { + pub(crate) async fn create_row(&self, row: RowMeta, start_row_id: Option) -> FlowyResult { let mut row_count = 0; let _ = self .modify(|pad| { diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs new file mode 100644 index 0000000000..104b6fbbdb --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -0,0 +1,248 @@ +use crate::dart_notification::{send_dart_notification, GridNotification}; +use crate::manager::GridUser; +use crate::services::block_meta_editor::ClientGridBlockMetaEditor; +use crate::services::persistence::block_index::BlockIndexPersistence; +use crate::services::row::{make_block_row_ids, make_rows_from_row_metas, GridBlockSnapshot}; + +use dashmap::DashMap; +use flowy_error::FlowyResult; +use flowy_grid_data_model::entities::{ + CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, + GridBlockOrder, RowMeta, RowMetaChangeset, RowOrder, +}; +use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; +use flowy_revision::{RevisionManager, RevisionPersistence}; +use std::collections::HashMap; +use std::sync::Arc; + +pub(crate) struct GridBlockMetaEditorManager { + grid_id: String, + user: Arc, + editor_map: DashMap>, + persistence: Arc, +} + +impl GridBlockMetaEditorManager { + pub(crate) async fn new( + grid_id: &str, + user: &Arc, + blocks: Vec, + persistence: Arc, + ) -> FlowyResult { + let editor_map = make_block_meta_editor_map(user, blocks).await?; + let user = user.clone(); + let grid_id = grid_id.to_owned(); + let manager = Self { + grid_id, + user, + editor_map, + persistence, + }; + Ok(manager) + } + + // #[tracing::instrument(level = "trace", skip(self))] + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + debug_assert!(!block_id.is_empty()); + match self.editor_map.get(block_id) { + None => { + tracing::error!("The is a fatal error, block is not exist"); + let editor = Arc::new(make_block_meta_editor(&self.user, block_id).await?); + self.editor_map.insert(block_id.to_owned(), editor.clone()); + Ok(editor) + } + Some(editor) => Ok(editor.clone()), + } + } + + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + let block_id = self.persistence.get_block_id(row_id)?; + Ok(self.get_editor(&block_id).await?) + } + + pub(crate) async fn create_row( + &self, + block_id: &str, + row_meta: RowMeta, + start_row_id: Option, + ) -> FlowyResult { + let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?; + let editor = self.get_editor(&row_meta.block_id).await?; + let row_count = editor.create_row(row_meta, start_row_id).await?; + self.notify_block_did_update_row(block_id).await?; + Ok(row_count) + } + + pub(crate) async fn insert_row( + &self, + rows_by_block_id: HashMap>, + ) -> FlowyResult> { + let mut changesets = vec![]; + for (block_id, row_metas) in rows_by_block_id { + let editor = self.get_editor(&block_id).await?; + let mut row_count = 0; + for row in &row_metas { + let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; + row_count = editor.create_row(row.clone(), None).await?; + } + changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); + let _ = self.notify_block_did_update_row(&block_id).await?; + } + + Ok(changesets) + } + + pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { + let mut changesets = vec![]; + for block_row_ids in make_block_row_ids(&row_orders) { + let editor = self.get_editor(&block_row_ids.block_id).await?; + let row_count = editor.delete_rows(block_row_ids.row_ids).await?; + + let changeset = GridBlockMetaChangeset::from_row_count(&block_row_ids.block_id, row_count); + changesets.push(changeset); + } + + Ok(changesets) + } + + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let _ = editor.update_row(changeset.clone()).await?; + let _ = self.notify_block_did_update_row(&editor.block_id).await?; + Ok(()) + } + + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + let row_id = changeset.row_id.clone(); + let editor = self.get_editor_from_row_id(&row_id).await?; + let row_changeset: RowMetaChangeset = changeset.clone().into(); + let _ = editor.update_row(row_changeset).await?; + + let cell_notification_data = CellNotificationData { + grid_id: changeset.grid_id, + field_id: changeset.field_id, + row_id: changeset.row_id, + content: changeset.data, + }; + self.notify_did_update_cell(cell_notification_data).await?; + Ok(()) + } + + pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult>> { + let editor = self.get_editor_from_row_id(row_id).await?; + let row_ids = vec![row_id.to_owned()]; + let mut row_metas = editor.get_row_metas(Some(row_ids)).await?; + if row_metas.is_empty() { + Ok(None) + } else { + Ok(row_metas.pop()) + } + } + + pub(crate) async fn make_block_snapshots(&self, block_ids: Vec) -> FlowyResult> { + let mut snapshots = vec![]; + for block_id in block_ids { + let editor = self.get_editor(&block_id).await?; + let row_metas = editor.get_row_metas(None).await?; + snapshots.push(GridBlockSnapshot { block_id, row_metas }); + } + Ok(snapshots) + } + + // Optimization: Using the shared memory(Arc, Cow,etc.) to reduce memory usage. + #[allow(dead_code)] + pub async fn get_cell_metas( + &self, + block_ids: Vec, + field_id: &str, + row_ids: Option>, + ) -> FlowyResult> { + let mut block_cell_metas = vec![]; + for block_id in block_ids { + let editor = self.get_editor(&block_id).await?; + let cell_metas = editor.get_cell_metas(field_id, &row_ids).await?; + block_cell_metas.extend(cell_metas); + } + Ok(block_cell_metas) + } + + async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { + let block_order: GridBlockOrder = block_id.into(); + send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock) + .payload(block_order) + .send(); + Ok(()) + } + + async fn notify_did_update_cell(&self, data: CellNotificationData) -> FlowyResult<()> { + let id = format!("{}:{}", data.row_id, data.field_id); + send_dart_notification(&id, GridNotification::DidUpdateCell) + .payload(data) + .send(); + Ok(()) + } + + #[allow(dead_code)] + async fn notify_did_update_row(&self, row_id: &str, field_metas: &[FieldMeta]) -> FlowyResult<()> { + match self.get_row_meta(row_id).await? { + None => {} + Some(row_meta) => { + let row_metas = vec![row_meta]; + if let Some(row) = make_rows_from_row_metas(field_metas, &row_metas).pop() { + send_dart_notification(row_id, GridNotification::DidUpdateRow) + .payload(row) + .send(); + } + } + } + Ok(()) + + // + // let field_meta_map = field_metas + // .iter() + // .map(|field_meta| (&field_meta.id, field_meta)) + // .collect::>(); + // + // let mut cells = vec![]; + // changeset + // .cell_by_field_id + // .into_iter() + // .for_each( + // |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) { + // None => {} + // Some((_, cell)) => cells.push(cell), + // }, + // ); + // + // if !cells.is_empty() { + // send_dart_notification(&changeset.row_id, GridNotification::DidUpdateRow) + // .payload(RepeatedCell::from(cells)) + // .send(); + // } + // Ok(()) + } +} + +async fn make_block_meta_editor_map( + user: &Arc, + blocks: Vec, +) -> FlowyResult>> { + let editor_map = DashMap::new(); + for block in blocks { + let editor = make_block_meta_editor(user, &block.block_id).await?; + editor_map.insert(block.block_id, Arc::new(editor)); + } + + Ok(editor_map) +} + +async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { + let token = user.token()?; + let user_id = user.user_id()?; + let pool = user.db_pool()?; + + let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache)); + let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence); + ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 2afdadb2f4..b3e1eb37f9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -43,7 +43,7 @@ const NO: &str = "No"; impl CellDataOperation for CheckboxTypeOption { fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { - if !type_option_cell_data.is_text() || !type_option_cell_data.is_checkbox() { + if !type_option_cell_data.is_checkbox() { return String::new(); } let cell_data = type_option_cell_data.data; @@ -58,7 +58,7 @@ impl CellDataOperation for CheckboxTypeOption { fn apply_changeset>( &self, changeset: T, - cell_meta: Option, + _cell_meta: Option, ) -> Result { let changeset = changeset.into(); let s = match string_to_bool(&changeset) { @@ -84,6 +84,7 @@ fn string_to_bool(bool_str: &str) -> bool { #[cfg(test)] mod tests { + use crate::services::field::type_options::checkbox_type_option::{NO, YES}; use crate::services::field::CheckboxTypeOption; use crate::services::field::FieldBuilder; use crate::services::row::CellDataOperation; @@ -94,17 +95,22 @@ mod tests { let type_option = CheckboxTypeOption::default(); let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); - assert_eq!(type_option.apply_changeset("true").unwrap(), "1".to_owned()); - assert_eq!(type_option.apply_changeset("1").unwrap(), "1".to_owned()); - assert_eq!(type_option.apply_changeset("yes").unwrap(), "1".to_owned()); + let data = type_option.apply_changeset("true", None).unwrap(); + assert_eq!(type_option.decode_cell_data(data, &field_meta), YES); - assert_eq!(type_option.apply_changeset("false").unwrap(), "0".to_owned()); - assert_eq!(type_option.apply_changeset("no").unwrap(), "0".to_owned()); - assert_eq!(type_option.apply_changeset("123").unwrap(), "0".to_owned()); + let data = type_option.apply_changeset("1", None).unwrap(); + assert_eq!(type_option.decode_cell_data(data, &field_meta), YES); - assert_eq!( - type_option.decode_cell_data("1".to_owned(), &field_meta), - "1".to_owned() - ); + let data = type_option.apply_changeset("yes", None).unwrap(); + assert_eq!(type_option.decode_cell_data(data, &field_meta), YES); + + let data = type_option.apply_changeset("false", None).unwrap(); + assert_eq!(type_option.decode_cell_data(data, &field_meta), NO); + + let data = type_option.apply_changeset("no", None).unwrap(); + assert_eq!(type_option.decode_cell_data(data, &field_meta), NO); + + let data = type_option.apply_changeset("123", None).unwrap(); + assert_eq!(type_option.decode_cell_data(data, &field_meta), NO); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 6472b91bb7..b89431add8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -66,7 +66,7 @@ impl CellDataOperation for DateTypeOption { fn apply_changeset>( &self, changeset: T, - cell_meta: Option, + _cell_meta: Option, ) -> Result { let changeset = changeset.into(); if let Err(e) = changeset.parse::() { @@ -282,7 +282,7 @@ mod tests { #[should_panic] fn date_description_invalid_data_test() { let type_option = DateTypeOption::default(); - type_option.apply_changeset("he").unwrap(); + type_option.apply_changeset("he", None).unwrap(); } fn data(s: &str) -> String { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index b0b5967a9d..7b03adfc74 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -104,7 +104,7 @@ impl CellDataOperation for NumberTypeOption { fn apply_changeset>( &self, changeset: T, - cell_meta: Option, + _cell_meta: Option, ) -> Result { let changeset = changeset.into(); let data = self.strip_symbol(changeset); diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 5dee72dec7..ad95fe6a54 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -5,15 +5,13 @@ use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellD use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::{ErrorCode, FlowyError, FlowyResult}; +use flowy_error::{ErrorCode, FlowyError}; use flowy_grid_data_model::entities::{ CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry, }; -use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; -use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use flowy_grid_data_model::parser::NotEmptyUuid; use serde::{Deserialize, Serialize}; use std::str::FromStr; -use uuid::Uuid; pub const SELECTION_IDS_SEPARATOR: &str = ","; @@ -66,9 +64,9 @@ impl CellDataOperation for SingleSelectTypeOption { return String::new(); } - match select_option_ids(type_option_cell_data.data).pop() { + match select_option_ids(type_option_cell_data.data).first() { None => String::new(), - Some(option_id) => match self.options.iter().find(|option| option.id == option_id) { + Some(option_id) => match self.options.iter().find(|option| &option.id == option_id) { None => String::new(), Some(option) => option.name.clone(), }, @@ -92,7 +90,7 @@ impl CellDataOperation for SingleSelectTypeOption { new_cell_data = "".to_string() } - return Ok(TypeOptionCellData::new(&new_cell_data, self.field_type()).json()); + Ok(TypeOptionCellData::new(&new_cell_data, self.field_type()).json()) } } @@ -416,7 +414,7 @@ impl std::default::Default for SelectOptionColor { } } -fn make_select_context_from(cell_meta: &Option, options: &Vec) -> Vec { +fn make_select_context_from(cell_meta: &Option, options: &[SelectOption]) -> Vec { match cell_meta { None => vec![], Some(cell_meta) => { @@ -434,16 +432,97 @@ fn make_select_context_from(cell_meta: &Option, options: &Vec>( &self, changeset: T, - cell_meta: Option, + _cell_meta: Option, ) -> Result { let data = changeset.into(); if data.len() > 10000 { @@ -85,29 +85,25 @@ mod tests { let done_option_id = done_option.id.clone(); let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); let single_select_field_meta = FieldBuilder::new(single_select).build(); - let data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); + let cell_data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); assert_eq!( - type_option.decode_cell_data(data, &single_select_field_meta), + type_option.decode_cell_data(cell_data, &single_select_field_meta), "Done".to_owned() ); // Multiple select let google_option = SelectOption::new("Google"); - let google_option_id = google_option.id.clone(); let facebook_option = SelectOption::new("Facebook"); - let face_option_id = facebook_option.id.clone(); + let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); + let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).cell_data(); let multi_select = MultiSelectTypeOptionBuilder::default() .option(google_option) - .option(facebook_option) - .option(SelectOption::new("Twitter")); + .option(facebook_option); let multi_select_field_meta = FieldBuilder::new(multi_select).build(); - let data = TypeOptionCellData::new( - &vec![google_option_id, face_option_id].join(SELECTION_IDS_SEPARATOR), - FieldType::SingleSelect, - ) - .json(); + let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta); + let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap(); assert_eq!( - type_option.decode_cell_data(data, &multi_select_field_meta), + type_option.decode_cell_data(cell_data, &multi_select_field_meta), "Google,Facebook".to_owned() ); diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 32dfb43668..cddafd3fdd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,6 +1,6 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; -use crate::services::block_meta_editor::GridBlockMetaEditorManager; +use crate::services::block_meta_manager::GridBlockMetaEditorManager; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; @@ -154,7 +154,7 @@ impl ClientGridEditor { pub async fn get_field_meta(&self, field_id: &str) -> Option { let field_meta = self.pad.read().await.get_field(field_id)?.clone(); - return Some(field_meta); + Some(field_meta) } pub async fn get_field_metas(&self, field_ids: Option>) -> FlowyResult> @@ -285,7 +285,7 @@ impl ClientGridEditor { match self.pad.read().await.get_field(&changeset.field_id) { None => { let msg = format!("Field not found with id: {}", &changeset.field_id); - return Err(FlowyError::internal().context(msg)); + Err(FlowyError::internal().context(msg)) } Some(field_meta) => { // Update the changeset.data property with the return value. diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 88e7fbec10..d6ca2d5c45 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 block_meta_editor; +mod block_meta_manager; pub mod cell; pub mod field; pub mod grid_editor; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 22fc0f14ae..0a0da4df57 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,5 +1,6 @@ use crate::services::row::apply_cell_data_changeset; +use crate::services::field::SelectOptionCellChangeset; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; @@ -44,6 +45,22 @@ impl<'a> CreateRowMetaBuilder<'a> { } } + pub fn add_select_option_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> { + match self.field_meta_map.get(&field_id.to_owned()) { + None => { + let msg = format!("Invalid field_id: {}", field_id); + Err(FlowyError::internal().context(msg)) + } + Some(field_meta) => { + let cell_data = SelectOptionCellChangeset::from_insert(&data).cell_data(); + let data = apply_cell_data_changeset(&cell_data, None, field_meta)?; + let cell = CellMeta::new(field_id, data); + self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); + Ok(()) + } + } + } + #[allow(dead_code)] pub fn height(mut self, height: i32) -> Self { self.payload.height = height; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs index e88ed4ffb9..38a081f6e7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs @@ -1,6 +1,6 @@ use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; -use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; +use flowy_grid_data_model::parser::NotEmptyUuid; #[derive(ProtoBuf, Default)] pub struct RowIdentifierPayload { diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 9cc8e078e0..9af437a40f 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -8,16 +8,27 @@ pub fn make_default_grid() -> BuildGridContext { .visibility(true) .build(); + // single select let single_select = SingleSelectTypeOptionBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Unknown")) .option(SelectOption::new("Progress")); - let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build(); + //multiple select + let multi_select = MultiSelectTypeOptionBuilder::default() + .option(SelectOption::new("A")) + .option(SelectOption::new("B")) + .option(SelectOption::new("C")); + let multi_select_field = FieldBuilder::new(multi_select) + .name("Alphabet") + .visibility(true) + .build(); + GridBuilder::default() .add_field(text_field) .add_field(single_select_field) + .add_field(multi_select_field) .add_empty_row() .add_empty_row() .add_empty_row() diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 5ac780519b..f031c00743 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -2,7 +2,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use chrono::NaiveDateTime; use flowy_grid::services::field::{ - MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, + MultiSelectTypeOption, SelectOption, SelectOptionCellChangeset, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, }; use flowy_grid::services::row::{apply_cell_data_changeset, decode_cell_data, CellDataOperation, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ @@ -233,37 +233,31 @@ async fn grid_row_add_cells_test() { for field in &test.field_metas { match field.field_type { FieldType::RichText => { - let data = apply_cell_data_changeset("hello world", field).unwrap(); - builder.add_cell(&field.id, data).unwrap(); + builder.add_cell(&field.id, "hello world".to_owned()).unwrap(); } FieldType::Number => { - let data = apply_cell_data_changeset("¥18,443", field).unwrap(); - builder.add_cell(&field.id, data).unwrap(); + builder.add_cell(&field.id, "18,443".to_owned()).unwrap(); } FieldType::DateTime => { - let data = apply_cell_data_changeset("1647251762", field).unwrap(); - builder.add_cell(&field.id, data).unwrap(); + builder.add_cell(&field.id, "1647251762".to_owned()).unwrap(); } FieldType::SingleSelect => { let type_option = SingleSelectTypeOption::from(field); - let options = type_option.options.first().unwrap(); - let data = type_option.apply_changeset(&options.id).unwrap(); - builder.add_cell(&field.id, data).unwrap(); + let option = type_option.options.first().unwrap(); + builder.add_select_option_cell(&field.id, option.id.clone()).unwrap(); } FieldType::MultiSelect => { let type_option = MultiSelectTypeOption::from(field); - let options = type_option + let ops_ids = type_option .options .iter() .map(|option| option.id.clone()) .collect::>() .join(SELECTION_IDS_SEPARATOR); - let data = type_option.apply_changeset(&options).unwrap(); - builder.add_cell(&field.id, data).unwrap(); + builder.add_select_option_cell(&field.id, ops_ids).unwrap(); } FieldType::Checkbox => { - let data = apply_cell_data_changeset("false", field).unwrap(); - builder.add_cell(&field.id, data).unwrap(); + builder.add_cell(&field.id, "false".to_string()).unwrap(); } } } @@ -272,61 +266,6 @@ async fn grid_row_add_cells_test() { test.run_scripts(scripts).await; } -#[tokio::test] -async fn grid_row_add_selection_cell_test() { - let mut test = GridEditorTest::new().await; - let mut builder = CreateRowMetaBuilder::new(&test.field_metas); - let uuid = uuid::Uuid::new_v4().to_string(); - let mut single_select_field_id = "".to_string(); - let mut multi_select_field_id = "".to_string(); - for field in &test.field_metas { - match field.field_type { - FieldType::SingleSelect => { - single_select_field_id = field.id.clone(); - // The element must be parsed as uuid - assert!(builder.add_cell(&field.id, "data".to_owned()).is_err()); - // // The data should not be empty - assert!(builder.add_cell(&field.id, "".to_owned()).is_err()); - // The element must be parsed as uuid - assert!(builder.add_cell(&field.id, "1,2,3".to_owned()).is_err(),); - // The separator must be comma - assert!(builder.add_cell(&field.id, format!("{}. {}", &uuid, &uuid),).is_err()); - // - - assert!(builder.add_cell(&field.id, uuid.clone()).is_ok()); - assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok()); - } - FieldType::MultiSelect => { - multi_select_field_id = field.id.clone(); - assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok()); - } - _ => {} - } - } - let context = builder.build(); - assert_eq!( - &context - .cell_by_field_id - .get(&single_select_field_id) - .as_ref() - .unwrap() - .data, - &uuid - ); - assert_eq!( - context - .cell_by_field_id - .get(&multi_select_field_id) - .as_ref() - .unwrap() - .data, - format!("{},{}", &uuid, &uuid) - ); - - let scripts = vec![CreateRow { context }]; - test.run_scripts(scripts).await; -} - #[tokio::test] async fn grid_row_add_date_cell_test() { let mut test = GridEditorTest::new().await; @@ -375,11 +314,11 @@ async fn grid_cell_update() { FieldType::DateTime => "123".to_string(), FieldType::SingleSelect => { let type_option = SingleSelectTypeOption::from(field_meta); - type_option.options.first().unwrap().id.clone() + SelectOptionCellChangeset::from_insert(&type_option.options.first().unwrap().id).cell_data() } FieldType::MultiSelect => { let type_option = MultiSelectTypeOption::from(field_meta); - type_option.options.first().unwrap().id.clone() + SelectOptionCellChangeset::from_insert(&type_option.options.first().unwrap().id).cell_data() } FieldType::Checkbox => "1".to_string(), }; @@ -400,8 +339,8 @@ async fn grid_cell_update() { FieldType::RichText => ("1".to_string().repeat(10001), true), FieldType::Number => ("abc".to_string(), true), FieldType::DateTime => ("abc".to_string(), true), - FieldType::SingleSelect => ("abc".to_string(), true), - FieldType::MultiSelect => ("abc".to_string(), true), + FieldType::SingleSelect => (SelectOptionCellChangeset::from_insert("abc").cell_data(), false), + FieldType::MultiSelect => (SelectOptionCellChangeset::from_insert("abc").cell_data(), false), FieldType::Checkbox => ("2".to_string(), false), }; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 858e9826cf..9c3cfd53d7 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,8 +3,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldType, - GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, + BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder, + FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, }; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_sync::client_grid::GridBuilder; @@ -89,7 +89,7 @@ impl GridEditorTest { let view_data: Bytes = build_context.try_into().unwrap(); let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); - let field_metas = editor.get_field_metas(None).await.unwrap(); + let field_metas = editor.get_field_metas::(None).await.unwrap(); let grid_blocks = editor.get_block_metas().await.unwrap(); let row_metas = get_row_metas(&editor).await; @@ -125,12 +125,12 @@ impl GridEditorTest { } self.editor.create_field(params).await.unwrap(); - self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas::(None).await.unwrap(); assert_eq!(self.field_count, self.field_metas.len()); } EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); - self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas::(None).await.unwrap(); } EditorScript::DeleteField { field_meta } => { if self.editor.contain_field(&field_meta.id).await { @@ -138,17 +138,20 @@ impl GridEditorTest { } self.editor.delete_field(&field_meta.id).await.unwrap(); - self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas::(None).await.unwrap(); assert_eq!(self.field_count, self.field_metas.len()); } EditorScript::AssertFieldCount(count) => { - assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count); + assert_eq!( + self.editor.get_field_metas::(None).await.unwrap().len(), + count + ); } EditorScript::AssertFieldEqual { field_index, field_meta, } => { - let field_metas = self.editor.get_field_metas(None).await.unwrap(); + let field_metas = self.editor.get_field_metas::(None).await.unwrap(); assert_eq!(field_metas[field_index].clone(), field_meta); } EditorScript::CreateBlock { block } => { 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 87a35b822d..d3cb9f7f69 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,5 +1,5 @@ use crate::entities::{FieldMeta, FieldType, RowMeta}; -use crate::parser::{NotEmptyStr, NotEmptyUuid}; +use crate::parser::NotEmptyUuid; use flowy_derive::ProtoBuf; use flowy_error_code::ErrorCode; use std::collections::HashMap; @@ -422,6 +422,7 @@ pub struct CreateFieldPayload { pub start_field_id: Option, } +#[derive(Clone)] pub struct CreateFieldParams { pub grid_id: String, pub field: Field, diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index de8ac320f3..cf48a70823 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -396,7 +396,7 @@ impl std::convert::From for RowMetaChangeset { let field_id = changeset.field_id; let cell_meta = CellMeta { field_id: field_id.clone(), - data: changeset.data.unwrap_or("".to_owned()), + data: changeset.data.unwrap_or_else(|| "".to_owned()), }; cell_by_field_id.insert(field_id, cell_meta); diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs index e2e2c75a6e..d011b76000 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs @@ -4,8 +4,5 @@ mod grid; pub use grid::*; -mod type_option; -pub use type_option::*; - mod meta; pub use meta::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs deleted file mode 100644 index 1cad4b09e8..0000000000 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/type_option.rs +++ /dev/null @@ -1,978 +0,0 @@ -// This file is generated by rust-protobuf 2.25.2. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![cfg_attr(rustfmt, rustfmt::skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `type_option.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 SelectOption { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub color: SelectOptionColor, - // 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()) - } - - // .SelectOptionColor color = 3; - - - pub fn get_color(&self) -> SelectOptionColor { - self.color - } - pub fn clear_color(&mut self) { - self.color = SelectOptionColor::Purple; - } - - // Param is passed by value, moved - pub fn set_color(&mut self, v: SelectOptionColor) { - self.color = v; - } -} - -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_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.color, 3, &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.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 != SelectOptionColor::Purple { - my_size += ::protobuf::rt::enum_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 != SelectOptionColor::Purple { - os.write_enum(3, ::protobuf::ProtobufEnum::value(&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::ProtobufTypeEnum>( - "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 = SelectOptionColor::Purple; - 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 SelectOptionCellChangesetPayload { - // message fields - pub grid_id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - // message oneof groups - pub one_of_insert_option_id: ::std::option::Option, - pub one_of_delete_option_id: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SelectOptionCellChangesetPayload { - fn default() -> &'a SelectOptionCellChangesetPayload { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id { - insert_option_id(::std::string::String), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id { - delete_option_id(::std::string::String), -} - -impl SelectOptionCellChangesetPayload { - pub fn new() -> SelectOptionCellChangesetPayload { - ::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()) - } - - // 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 insert_option_id = 4; - - - pub fn get_insert_option_id(&self) -> &str { - match self.one_of_insert_option_id { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v)) => v, - _ => "", - } - } - pub fn clear_insert_option_id(&mut self) { - self.one_of_insert_option_id = ::std::option::Option::None; - } - - pub fn has_insert_option_id(&self) -> bool { - match self.one_of_insert_option_id { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_insert_option_id(&mut self, v: ::std::string::String) { - self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) - } - - // Mutable pointer to the field. - pub fn mut_insert_option_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(_)) = self.one_of_insert_option_id { - } else { - self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(::std::string::String::new())); - } - match self.one_of_insert_option_id { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_insert_option_id(&mut self) -> ::std::string::String { - if self.has_insert_option_id() { - match self.one_of_insert_option_id.take() { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(v)) => v, - _ => panic!(), - } - } else { - ::std::string::String::new() - } - } - - // string delete_option_id = 5; - - - pub fn get_delete_option_id(&self) -> &str { - match self.one_of_delete_option_id { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v)) => v, - _ => "", - } - } - pub fn clear_delete_option_id(&mut self) { - self.one_of_delete_option_id = ::std::option::Option::None; - } - - pub fn has_delete_option_id(&self) -> bool { - match self.one_of_delete_option_id { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_delete_option_id(&mut self, v: ::std::string::String) { - self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) - } - - // Mutable pointer to the field. - pub fn mut_delete_option_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(_)) = self.one_of_delete_option_id { - } else { - self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(::std::string::String::new())); - } - match self.one_of_delete_option_id { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_delete_option_id(&mut self) -> ::std::string::String { - if self.has_delete_option_id() { - match self.one_of_delete_option_id.take() { - ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(v)) => v, - _ => panic!(), - } - } else { - ::std::string::String::new() - } - } -} - -impl ::protobuf::Message for SelectOptionCellChangesetPayload { - 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 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_delete_option_id = ::std::option::Option::Some(SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(is.read_string()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } - if !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 ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { - match v { - &SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { - my_size += ::protobuf::rt::string_size(4, &v); - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { - match v { - &SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { - my_size += ::protobuf::rt::string_size(5, &v); - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } - if !self.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 ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { - match v { - &SelectOptionCellChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { - os.write_string(4, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { - match v { - &SelectOptionCellChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { - os.write_string(5, v)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> SelectOptionCellChangesetPayload { - SelectOptionCellChangesetPayload::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: &SelectOptionCellChangesetPayload| { &m.grid_id }, - |m: &mut SelectOptionCellChangesetPayload| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &SelectOptionCellChangesetPayload| { &m.row_id }, - |m: &mut SelectOptionCellChangesetPayload| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &SelectOptionCellChangesetPayload| { &m.field_id }, - |m: &mut SelectOptionCellChangesetPayload| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "insert_option_id", - SelectOptionCellChangesetPayload::has_insert_option_id, - SelectOptionCellChangesetPayload::get_insert_option_id, - )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "delete_option_id", - SelectOptionCellChangesetPayload::has_delete_option_id, - SelectOptionCellChangesetPayload::get_delete_option_id, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOptionCellChangesetPayload", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SelectOptionCellChangesetPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOptionCellChangesetPayload::new) - } -} - -impl ::protobuf::Clear for SelectOptionCellChangesetPayload { - fn clear(&mut self) { - self.grid_id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.one_of_insert_option_id = ::std::option::Option::None; - self.one_of_delete_option_id = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SelectOptionCellChangesetPayload { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOptionCellChangesetPayload { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct SelectOptionContext { - // message fields - pub options: ::protobuf::RepeatedField, - pub select_options: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SelectOptionContext { - fn default() -> &'a SelectOptionContext { - ::default_instance() - } -} - -impl SelectOptionContext { - pub fn new() -> SelectOptionContext { - ::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()) - } - - // repeated .SelectOption select_options = 2; - - - pub fn get_select_options(&self) -> &[SelectOption] { - &self.select_options - } - pub fn clear_select_options(&mut self) { - self.select_options.clear(); - } - - // Param is passed by value, moved - pub fn set_select_options(&mut self, v: ::protobuf::RepeatedField) { - self.select_options = v; - } - - // Mutable pointer to the field. - pub fn mut_select_options(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.select_options - } - - // Take field - pub fn take_select_options(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.select_options, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for SelectOptionContext { - fn is_initialized(&self) -> bool { - for v in &self.options { - if !v.is_initialized() { - return false; - } - }; - for v in &self.select_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 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.select_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; - for value in &self.options { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - for value in &self.select_options { - 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.options { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - for v in &self.select_options { - 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() -> SelectOptionContext { - SelectOptionContext::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: &SelectOptionContext| { &m.options }, - |m: &mut SelectOptionContext| { &mut m.options }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "select_options", - |m: &SelectOptionContext| { &m.select_options }, - |m: &mut SelectOptionContext| { &mut m.select_options }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOptionContext", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SelectOptionContext { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOptionContext::new) - } -} - -impl ::protobuf::Clear for SelectOptionContext { - fn clear(&mut self) { - self.options.clear(); - self.select_options.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SelectOptionContext { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOptionContext { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum SelectOptionColor { - Purple = 0, - Pink = 1, - LightPink = 2, - Orange = 3, - Yellow = 4, - Lime = 5, - Green = 6, - Aqua = 7, - Blue = 8, -} - -impl ::protobuf::ProtobufEnum for SelectOptionColor { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(SelectOptionColor::Purple), - 1 => ::std::option::Option::Some(SelectOptionColor::Pink), - 2 => ::std::option::Option::Some(SelectOptionColor::LightPink), - 3 => ::std::option::Option::Some(SelectOptionColor::Orange), - 4 => ::std::option::Option::Some(SelectOptionColor::Yellow), - 5 => ::std::option::Option::Some(SelectOptionColor::Lime), - 6 => ::std::option::Option::Some(SelectOptionColor::Green), - 7 => ::std::option::Option::Some(SelectOptionColor::Aqua), - 8 => ::std::option::Option::Some(SelectOptionColor::Blue), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [SelectOptionColor] = &[ - SelectOptionColor::Purple, - SelectOptionColor::Pink, - SelectOptionColor::LightPink, - SelectOptionColor::Orange, - SelectOptionColor::Yellow, - SelectOptionColor::Lime, - SelectOptionColor::Green, - SelectOptionColor::Aqua, - SelectOptionColor::Blue, - ]; - 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::("SelectOptionColor", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for SelectOptionColor { -} - -impl ::std::default::Default for SelectOptionColor { - fn default() -> Self { - SelectOptionColor::Purple - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOptionColor { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x11type_option.proto\"\\\n\x0cSelectOption\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12(\n\ - \x05color\x18\x03\x20\x01(\x0e2\x12.SelectOptionColorR\x05color\"\xfb\ - \x01\n\x20SelectOptionCellChangesetPayload\x12\x17\n\x07grid_id\x18\x01\ - \x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\ - \x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12*\n\x10insert_o\ - ption_id\x18\x04\x20\x01(\tH\0R\x0einsertOptionId\x12*\n\x10delete_optio\ - n_id\x18\x05\x20\x01(\tH\x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_\ - option_idB\x19\n\x17one_of_delete_option_id\"t\n\x13SelectOptionContext\ - \x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\ - \n\x0eselect_options\x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOption\ - s*y\n\x11SelectOptionColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\ - \x01\x12\r\n\tLightPink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yel\ - low\x10\x04\x12\x08\n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\ - \x04Aqua\x10\x07\x12\x08\n\x04Blue\x10\x08b\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/proto/type_option.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto deleted file mode 100644 index 5f375f93aa..0000000000 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/type_option.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -message SelectOption { - string id = 1; - string name = 2; - SelectOptionColor color = 3; -} -message SelectOptionCellChangesetPayload { - string grid_id = 1; - string row_id = 2; - string field_id = 3; - oneof one_of_insert_option_id { string insert_option_id = 4; }; - oneof one_of_delete_option_id { string delete_option_id = 5; }; -} -message SelectOptionContext { - repeated SelectOption options = 1; - repeated SelectOption select_options = 2; -} -enum SelectOptionColor { - Purple = 0; - Pink = 1; - LightPink = 2; - Orange = 3; - Yellow = 4; - Lime = 5; - Green = 6; - Aqua = 7; - Blue = 8; -} From bf8a752b4df9324a5067ef45d81e5bf90d73df28 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 16:36:59 +0800 Subject: [PATCH 102/179] fix: update row after field was changed --- .../app_flowy/lib/startup/deps_resolver.dart | 2 +- .../grid/field/field_editor_bloc.dart | 4 +-- .../application/grid/field/field_service.dart | 23 +++++++++++++--- .../grid/field/field_switch_bloc.dart | 18 ++++--------- .../grid/field/grid_header_bloc.dart | 10 +++---- .../application/grid/row/row_bloc.dart | 8 +++--- .../grid/src/widgets/header/field_editor.dart | 23 ++++++++-------- .../src/widgets/header/field_switcher.dart | 26 ++++++++++++++++--- .../grid/src/widgets/row/grid_row.dart | 8 +++--- 9 files changed, 75 insertions(+), 47 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 58ad1cf9cc..2b37642f39 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -172,7 +172,7 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (gridId, fieldLoader) => FieldEditorBloc( service: FieldService(gridId: gridId), fieldLoader: fieldLoader, diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart index dd27f66070..c38713862e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart @@ -11,11 +11,11 @@ part 'field_editor_bloc.freezed.dart'; class FieldEditorBloc extends Bloc { final FieldService service; - final FieldContextLoader _loader; + final EditFieldContextLoader _loader; FieldEditorBloc({ required this.service, - required FieldContextLoader fieldLoader, + required EditFieldContextLoader fieldLoader, }) : _loader = fieldLoader, super(FieldEditorState.initial(service.gridId)) { on( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 3ea1c46062..2336c4f340 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -112,11 +112,13 @@ class GridFieldCellContext extends Equatable { List get props => [field.id]; } -abstract class FieldContextLoader { +abstract class EditFieldContextLoader { Future> load(); + + Future> switchToField(String fieldId, FieldType fieldType); } -class NewFieldContextLoader extends FieldContextLoader { +class NewFieldContextLoader extends EditFieldContextLoader { final String gridId; NewFieldContextLoader({ required this.gridId, @@ -130,9 +132,18 @@ class NewFieldContextLoader extends FieldContextLoader { return GridEventGetEditFieldContext(payload).send(); } + + @override + Future> switchToField(String fieldId, FieldType fieldType) { + final payload = GetEditFieldContextPayload.create() + ..gridId = gridId + ..fieldType = fieldType; + + return GridEventGetEditFieldContext(payload).send(); + } } -class FieldContextLoaderAdaptor extends FieldContextLoader { +class FieldContextLoaderAdaptor extends EditFieldContextLoader { final String gridId; final Field field; @@ -150,4 +161,10 @@ class FieldContextLoaderAdaptor extends FieldContextLoader { return GridEventGetEditFieldContext(payload).send(); } + + @override + Future> switchToField(String fieldId, FieldType fieldType) async { + final fieldService = FieldService(gridId: gridId); + return fieldService.switchToField(fieldId, fieldType); + } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart index 802b39d95a..082c0decf4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart @@ -1,11 +1,8 @@ import 'dart:typed_data'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'field_service.dart'; part 'field_switch_bloc.freezed.dart'; @@ -15,15 +12,10 @@ class FieldSwitcherBloc extends Bloc { (event, emit) async { await event.map( toFieldType: (_ToFieldType value) async { - final fieldService = FieldService(gridId: state.gridId); - final result = await fieldService.switchToField(state.field.id, value.fieldType); - result.fold( - (newEditContext) { - final typeOptionData = Uint8List.fromList(newEditContext.typeOptionData); - emit(state.copyWith(field: newEditContext.gridField, typeOptionData: typeOptionData)); - }, - (err) => Log.error(err), - ); + emit(state.copyWith( + field: value.field, + typeOptionData: Uint8List.fromList(value.typeOptionData), + )); }, didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) { emit(state.copyWith(typeOptionData: value.typeOptionData)); @@ -41,7 +33,7 @@ class FieldSwitcherBloc extends Bloc { @freezed class FieldSwitchEvent with _$FieldSwitchEvent { - const factory FieldSwitchEvent.toFieldType(FieldType fieldType) = _ToFieldType; + const factory FieldSwitchEvent.toFieldType(Field field, List typeOptionData) = _ToFieldType; const factory FieldSwitchEvent.didUpdateTypeOptionData(Uint8List typeOptionData) = _DidUpdateTypeOptionData; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart index ae10505bc7..4145e23804 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -11,12 +11,12 @@ part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc { final FieldService service; - final GridFieldsListener fieldListener; + final GridFieldsListener _fieldListener; GridHeaderBloc({ required GridHeaderData data, required this.service, - }) : fieldListener = GridFieldsListener(gridId: data.gridId), + }) : _fieldListener = GridFieldsListener(gridId: data.gridId), super(GridHeaderState.initial(data.fields)) { on( (event, emit) async { @@ -36,19 +36,19 @@ class GridHeaderBloc extends Bloc { } Future _startListening() async { - fieldListener.updateFieldsNotifier.addPublishListener((result) { + _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), (err) => Log.error(err), ); }); - fieldListener.start(); + _fieldListener.start(); } @override Future close() async { - await fieldListener.stop(); + await _fieldListener.stop(); return super.close(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 3c29d82d46..418cb23e88 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -52,7 +52,7 @@ class RowBloc extends Bloc { } void _handleRowUpdate(_DidUpdateRow value, Emitter emit) { - final CellDataMap cellDataMap = _makeCellDatas(value.row); + final CellDataMap cellDataMap = _makeCellDatas(value.row, state.fields); emit(state.copyWith( row: Future(() => Some(value.row)), cellDataMap: Some(cellDataMap), @@ -63,7 +63,7 @@ class RowBloc extends Bloc { final optionRow = await state.row; final CellDataMap cellDataMap = optionRow.fold( () => CellDataMap.identity(), - (row) => _makeCellDatas(row), + (row) => _makeCellDatas(row, value.fields), ); emit(state.copyWith( @@ -107,9 +107,9 @@ class RowBloc extends Bloc { }); } - CellDataMap _makeCellDatas(Row row) { + CellDataMap _makeCellDatas(Row row, List fields) { var map = CellDataMap.new(); - for (final field in state.fields) { + for (final field in fields) { if (field.visibility) { map[field.id] = CellData( rowId: row.id, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index d568829558..3a41ee938b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -5,6 +5,7 @@ import 'package:app_flowy/workspace/application/grid/field/field_switch_bloc.dar import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_name_input.dart'; @@ -13,7 +14,7 @@ import 'field_switcher.dart'; class FieldEditor extends FlowyOverlayDelegate { final String gridId; final FieldEditorBloc _fieldEditorBloc; - final FieldContextLoader? fieldContextLoader; + final EditFieldContextLoader fieldContextLoader; FieldEditor({ required this.gridId, required this.fieldContextLoader, @@ -29,7 +30,7 @@ class FieldEditor extends FlowyOverlayDelegate { FlowyOverlay.of(context).remove(identifier()); FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( - child: _FieldEditorWidget(_fieldEditorBloc), + child: _FieldEditorWidget(_fieldEditorBloc, fieldContextLoader), constraints: BoxConstraints.loose(const Size(220, 400)), ), identifier: identifier(), @@ -55,7 +56,8 @@ class FieldEditor extends FlowyOverlayDelegate { class _FieldEditorWidget extends StatelessWidget { final FieldEditorBloc editorBloc; - const _FieldEditorWidget(this.editorBloc, {Key? key}) : super(key: key); + final EditFieldContextLoader fieldContextLoader; + const _FieldEditorWidget(this.editorBloc, this.fieldContextLoader, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -72,7 +74,7 @@ class _FieldEditorWidget extends StatelessWidget { const VSpace(10), const _FieldNameTextField(), const VSpace(10), - _FieldSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)), + _renderSwitchButton(context, field, state), ], ), ); @@ -80,16 +82,13 @@ class _FieldEditorWidget extends StatelessWidget { ), ); } -} -class _FieldSwitcher extends StatelessWidget { - final SwitchFieldContext switchContext; - const _FieldSwitcher(this.switchContext, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { + Widget _renderSwitchButton(BuildContext context, Field field, FieldEditorState state) { return FieldSwitcher( - switchContext: switchContext, + switchContext: SwitchFieldContext(state.gridId, field, state.typeOptionData), + onSwitchToField: (fieldId, fieldType) { + return fieldContextLoader.switchToField(fieldId, fieldType); + }, onUpdated: (field, typeOptionData) { context.read().add(FieldEditorEvent.switchField(field, typeOptionData)); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index 63816c7d74..decaaec611 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -7,6 +7,8 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart'; @@ -17,20 +19,26 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; import 'field_type_extension.dart'; - +import 'package:dartz/dartz.dart' show Either; import 'type_option/multi_select.dart'; import 'type_option/number.dart'; import 'type_option/single_select.dart'; typedef UpdateFieldCallback = void Function(Field, Uint8List); +typedef SwitchToFieldCallback = Future> Function( + String fieldId, + FieldType fieldType, +); class FieldSwitcher extends StatefulWidget { final SwitchFieldContext switchContext; final UpdateFieldCallback onUpdated; + final SwitchToFieldCallback onSwitchToField; const FieldSwitcher({ required this.switchContext, required this.onUpdated, + required this.onSwitchToField, Key? key, }) : super(key: key); @@ -79,8 +87,20 @@ class _FieldSwitcherState extends State { padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), hoverColor: theme.hover, onTap: () { - final list = FieldTypeList(onSelectField: (fieldType) { - context.read().add(FieldSwitchEvent.toFieldType(fieldType)); + final list = FieldTypeList(onSelectField: (newFieldType) { + widget.onSwitchToField(field.id, newFieldType).then((result) { + result.fold( + (editFieldContext) { + context.read().add( + FieldSwitchEvent.toFieldType( + editFieldContext.gridField, + editFieldContext.typeOptionData, + ), + ); + }, + (err) => Log.error(err), + ); + }); }); _showOverlay(context, list); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index d3ac6d8ce3..08d68f197a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -19,12 +19,12 @@ class GridRowWidget extends StatefulWidget { class _GridRowWidgetState extends State { late RowBloc _rowBloc; - late RowRegionStateNotifier _rowStateNotifier; + late _RegionStateNotifier _rowStateNotifier; @override void initState() { _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); - _rowStateNotifier = RowRegionStateNotifier(); + _rowStateNotifier = _RegionStateNotifier(); super.initState(); } @@ -72,7 +72,7 @@ class _RowLeading extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( + return Consumer<_RegionStateNotifier>( builder: (context, state, _) { return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null); }, @@ -140,7 +140,7 @@ class _RowCells extends StatelessWidget { } } -class RowRegionStateNotifier extends ChangeNotifier { +class _RegionStateNotifier extends ChangeNotifier { bool _onEnter = false; set onEnter(bool value) { From c82c6d9c6e9f9ed9068b096221dea2173e7207f5 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 17:07:46 +0800 Subject: [PATCH 103/179] fix: deserialize multiple select cell data issues --- .../grid/cell_bloc/cell_service.dart | 2 -- .../grid/cell_bloc/selection_editor_bloc.dart | 30 ++++++++++++------- .../grid/setting/setting_bloc.dart | 1 - .../header/type_option/multi_select.dart | 2 +- .../lib/src/flowy_overlay/flowy_overlay.dart | 2 +- .../lib/src/flowy_overlay/list_overlay.dart | 3 -- .../type_options/selection_type_option.rs | 23 ++++++++++++-- 7 files changed, 42 insertions(+), 21 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index b36727adcc..e1af022d95 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,9 +1,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; class CellService { CellService(); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index c6396138a9..e7f471dece 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -15,6 +15,7 @@ class SelectOptionEditorBloc extends Bloc close() async { + _delayOperation?.cancel(); await _fieldListener.stop(); await _cellListener.stop(); return super.close(); @@ -106,18 +108,24 @@ class SelectOptionEditorBloc extends Bloc add(SelectOptionEditorEvent.didReceiveOptions( - selectOptionContext.options, - selectOptionContext.selectOptions, - )), - (err) => Log.error(err), + result.fold( + (selectOptionContext) => add(SelectOptionEditorEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )), + (err) => Log.error(err), + ); + }, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart index 38071155af..bea2b87da6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart @@ -1,4 +1,3 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 99728aeffb..11d2c866ce 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -8,7 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'option_pannel.dart'; class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { - MultiSelectTypeOptionWidget _widget; + final MultiSelectTypeOptionWidget _widget; MultiSelectTypeOptionBuilder( String fieldId, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 0290cf18b3..1229745381 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -122,7 +122,7 @@ class OverlayItem { } class FlowyOverlayState extends State { - List _overlayList = []; + final List _overlayList = []; FlowyOverlayStyle style = FlowyOverlayStyle(); /// Insert a overlay widget which frame is set by the widget, not the component. diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart index 6c0a4019d1..16d3b55f47 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart @@ -1,8 +1,5 @@ import 'package:flowy_infra_ui/flowy_infra_ui_web.dart'; -import 'package:flowy_infra_ui/style_widget/decoration.dart'; import 'package:flutter/material.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:provider/provider.dart'; class ListOverlayFooter { Widget widget; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index ad95fe6a54..786cd2ce0d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -85,8 +85,10 @@ impl CellDataOperation for SingleSelectTypeOption { let select_option_changeset: SelectOptionCellChangeset = serde_json::from_str(&changeset)?; let new_cell_data: String; if let Some(insert_option_id) = select_option_changeset.insert_option_id { + tracing::trace!("Insert single select option: {}", &insert_option_id); new_cell_data = insert_option_id; } else { + tracing::trace!("Delete single select option"); new_cell_data = "".to_string() } @@ -127,6 +129,15 @@ pub struct MultiSelectTypeOption { } impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); +impl MultiSelectTypeOption { + pub fn get_cell_data(&self, cell_meta: &CellMeta) -> String { + match TypeOptionCellData::from_str(&cell_meta.data) { + Ok(type_option) => type_option.data, + Err(_) => String::new(), + } + } +} + impl SelectOptionOperation for MultiSelectTypeOption { fn insert_option(&mut self, new_option: SelectOption) { if let Some(index) = self.options.iter().position(|option| option.id == new_option.id) { @@ -185,16 +196,24 @@ impl CellDataOperation for MultiSelectTypeOption { .unwrap_or_else(|| "".to_owned()); } Some(cell_meta) => { - let mut selected_options = select_option_ids(cell_meta.data); + let cell_data = self.get_cell_data(&cell_meta); + let mut selected_options = select_option_ids(cell_data); if let Some(insert_option_id) = select_option_changeset.insert_option_id { - selected_options.push(insert_option_id); + tracing::trace!("Insert multi select option: {}", &insert_option_id); + if selected_options.contains(&insert_option_id) { + selected_options.retain(|id| id != &insert_option_id); + } else { + selected_options.push(insert_option_id); + } } if let Some(delete_option_id) = select_option_changeset.delete_option_id { + tracing::trace!("Delete multi select option: {}", &delete_option_id); selected_options.retain(|id| id != &delete_option_id); } new_cell_data = selected_options.join(SELECTION_IDS_SEPARATOR); + tracing::trace!("Multi select cell data: {}", &new_cell_data); } } From e15d335fed477813c7bec40f1f93b8c9254e26f4 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 20:15:00 +0800 Subject: [PATCH 104/179] chore: config checkbox ui --- .../grid/cell_bloc/cell_service.dart | 14 ++++ .../grid/cell_bloc/checkbox_cell_bloc.dart | 65 ++++++++++++++++--- .../grid/src/widgets/cell/checkbox_cell.dart | 15 ++++- .../dart_event/flowy-grid/dart_event.dart | 17 +++++ .../protobuf/flowy-grid/event_map.pbenum.dart | 6 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 7 +- .../rust-lib/flowy-grid/src/event_handler.rs | 13 ++++ frontend/rust-lib/flowy-grid/src/event_map.rs | 8 ++- .../src/protobuf/model/event_map.rs | 17 +++-- .../src/protobuf/proto/event_map.proto | 5 +- .../flowy-grid/src/services/grid_editor.rs | 7 ++ frontend/rust-lib/flowy-grid/src/util.rs | 8 ++- 12 files changed, 154 insertions(+), 28 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index e1af022d95..9bdd48c259 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,7 +1,9 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; class CellService { CellService(); @@ -19,4 +21,16 @@ class CellService { ..data = data; return GridEventUpdateCell(payload).send(); } + + Future> getCell({ + required String gridId, + required String fieldId, + required String rowId, + }) { + final payload = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + return GridEventGetCell(payload).send(); + } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index f5bc7e7c18..ae69176fd9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,5 +1,7 @@ +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -8,17 +10,32 @@ import 'cell_service.dart'; part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { - final CellService service; - // final CellData cellData; + final CellService _service; + final CellListener _listener; CheckboxCellBloc({ - required this.service, + required CellService service, required CellData cellData, - }) : super(CheckboxCellState.initial()) { + }) : _service = service, + _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + super(CheckboxCellState.initial(cellData)) { on( (event, emit) async { await event.map( - initial: (_InitialCell value) async {}, + initial: (_Initial value) { + _startListening(); + }, + select: (_Selected value) async { + service.updateCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + data: !state.isSelected ? "Yes" : "No", + ); + }, + didReceiveCellUpdate: (_DidReceiveCellUpdate value) { + emit(state.copyWith(isSelected: isSelected(value.cell))); + }, ); }, ); @@ -28,18 +45,48 @@ class CheckboxCellBloc extends Bloc { Future close() async { return super.close(); } + + void _startListening() { + _listener.updateCellNotifier.addPublishListener((result) { + result.fold( + (notificationData) async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + result.fold( + (cell) => add(CheckboxCellEvent.didReceiveCellUpdate(cell)), + (err) => Log.error(err), + ); + }, + (err) => Log.error(err), + ); + }); + _listener.start(); + } } @freezed class CheckboxCellEvent with _$CheckboxCellEvent { - const factory CheckboxCellEvent.initial() = _InitialCell; + const factory CheckboxCellEvent.initial() = _Initial; + const factory CheckboxCellEvent.select() = _Selected; + const factory CheckboxCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; } @freezed class CheckboxCellState with _$CheckboxCellState { const factory CheckboxCellState({ - required Cell? cell, + required CellData cellData, + required bool isSelected, }) = _CheckboxCellState; - factory CheckboxCellState.initial() => const CheckboxCellState(cell: null); + factory CheckboxCellState.initial(CellData cellData) { + return CheckboxCellState(cellData: cellData, isSelected: isSelected(cellData.cell)); + } +} + +bool isSelected(Cell? cell) { + final content = cell?.content ?? ""; + return content == "Yes"; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index 7e1fdf166a..b4095c71d9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -1,5 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -20,7 +22,7 @@ class _CheckboxCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellData); + _cellBloc = getIt(param1: widget.cellData)..add(const CheckboxCellEvent.initial()); super.initState(); } @@ -30,7 +32,16 @@ class _CheckboxCellState extends State { value: _cellBloc, child: BlocBuilder( builder: (context, state) { - return Container(); + final icon = state.isSelected ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck'); + return Align( + alignment: Alignment.centerLeft, + child: FlowyIconButton( + onPressed: () => context.read().add(const CheckboxCellEvent.select()), + iconPadding: EdgeInsets.zero, + icon: icon, + width: 23, + ), + ); }, ), ); 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 3003b4c6f8..a4871a6bef 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 @@ -239,6 +239,23 @@ class GridEventGetRow { } } +class GridEventGetCell { + CellIdentifierPayload request; + GridEventGetCell(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetCell.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Cell.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventUpdateCell { CellMetaChangeset request; GridEventUpdateCell(this.request); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 7c190dcd98..37032ec41b 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 @@ -24,8 +24,9 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent ApplySelectOptionChangeset = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); - static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); - static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); + static const GridEvent GetCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCell'); + static const GridEvent UpdateCell = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); static const $core.List values = [ GetGridData, @@ -42,6 +43,7 @@ class GridEvent extends $pb.ProtobufEnum { ApplySelectOptionChangeset, CreateRow, GetRow, + GetCell, UpdateCell, ApplySelectOptionCellChangeset, ]; 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 1c07877726..bc4b838bca 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 @@ -26,10 +26,11 @@ const GridEvent$json = const { const {'1': 'ApplySelectOptionChangeset', '2': 32}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, - const {'1': 'UpdateCell', '2': 70}, - const {'1': 'ApplySelectOptionCellChangeset', '2': 71}, + const {'1': 'GetCell', '2': 70}, + const {'1': 'UpdateCell', '2': 71}, + const {'1': 'ApplySelectOptionCellChangeset', '2': 72}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg4KClVwZGF0ZUNlbGwQRhIiCh5BcHBseVNlbGVjdE9wdGlvbkNlbGxDaGFuZ2VzZXQQRw=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSIgoeQXBwbHlTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0EEg='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 3d46349240..ec6dc9659e 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -190,6 +190,19 @@ pub(crate) async fn create_row_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn get_cell_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CellIdentifier = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_cell(¶ms).await { + None => data_result(Cell::new(¶ms.field_id, "".to_owned())), + Some(cell) => data_result(cell), + } +} + #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 711ad46255..8a4c68e468 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -21,6 +21,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) // Cell + .event(GridEvent::GetCell, get_cell_handler) .event(GridEvent::UpdateCell, update_cell_handler) // SelectOption .event(GridEvent::NewSelectOption, new_select_option_handler) @@ -80,9 +81,12 @@ pub enum GridEvent { #[event(input = "RowIdentifierPayload", output = "Row")] GetRow = 51, + #[event(input = "CellIdentifierPayload", output = "Cell")] + GetCell = 70, + #[event(input = "CellMetaChangeset")] - UpdateCell = 70, + UpdateCell = 71, #[event(input = "SelectOptionCellChangesetPayload")] - ApplySelectOptionCellChangeset = 71, + ApplySelectOptionCellChangeset = 72, } 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 ef26608bf1..d9cfbac578 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 @@ -39,8 +39,9 @@ pub enum GridEvent { ApplySelectOptionChangeset = 32, CreateRow = 50, GetRow = 51, - UpdateCell = 70, - ApplySelectOptionCellChangeset = 71, + GetCell = 70, + UpdateCell = 71, + ApplySelectOptionCellChangeset = 72, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -64,8 +65,9 @@ impl ::protobuf::ProtobufEnum for GridEvent { 32 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), - 70 => ::std::option::Option::Some(GridEvent::UpdateCell), - 71 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), + 70 => ::std::option::Option::Some(GridEvent::GetCell), + 71 => ::std::option::Option::Some(GridEvent::UpdateCell), + 72 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), _ => ::std::option::Option::None } } @@ -86,6 +88,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::ApplySelectOptionChangeset, GridEvent::CreateRow, GridEvent::GetRow, + GridEvent::GetCell, GridEvent::UpdateCell, GridEvent::ApplySelectOptionCellChangeset, ]; @@ -116,15 +119,15 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xd1\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xde\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\ lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x1e\n\ \x1aApplySelectOptionChangeset\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\ - \x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\"\n\x1eApplySelectOptionC\ - ellChangeset\x10Gb\x06proto3\ + \x06GetRow\x103\x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\ + \"\n\x1eApplySelectOptionCellChangeset\x10Hb\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 caddf2de41..1201bd759e 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 @@ -15,6 +15,7 @@ enum GridEvent { ApplySelectOptionChangeset = 32; CreateRow = 50; GetRow = 51; - UpdateCell = 70; - ApplySelectOptionCellChangeset = 71; + GetCell = 70; + UpdateCell = 71; + ApplySelectOptionCellChangeset = 72; } 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 cddafd3fdd..a91f0bb606 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,6 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_manager::GridBlockMetaEditorManager; +use crate::services::cell::CellIdentifier; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; @@ -264,6 +265,12 @@ impl ClientGridEditor { } } + pub async fn get_cell(&self, params: &CellIdentifier) -> Option { + let field_meta = self.get_field_meta(¶ms.field_id).await?; + let row_meta = self.block_meta_manager.get_row_meta(¶ms.row_id).await.ok()??; + make_cell(¶ms.field_id, &field_meta, &row_meta) + } + pub async fn get_cell_meta(&self, row_id: &str, field_id: &str) -> FlowyResult> { let row_meta = self.block_meta_manager.get_row_meta(row_id).await?; match row_meta { diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 9af437a40f..bbc2d1b642 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,5 +1,5 @@ use crate::services::field::*; -use flowy_grid_data_model::entities::BuildGridContext; +use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; use flowy_sync::client_grid::GridBuilder; pub fn make_default_grid() -> BuildGridContext { @@ -25,10 +25,16 @@ pub fn make_default_grid() -> BuildGridContext { .visibility(true) .build(); + let checkbox_field = FieldBuilder::from_field_type(&FieldType::Checkbox) + .name("isReady") + .visibility(true) + .build(); + GridBuilder::default() .add_field(text_field) .add_field(single_select_field) .add_field(multi_select_field) + .add_field(checkbox_field) .add_empty_row() .add_empty_row() .add_empty_row() From 11627269bee2cdbcc9b64adfca5fdfe01411937d Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 20:54:22 +0800 Subject: [PATCH 105/179] chore: config number ui --- .../app_flowy/lib/startup/deps_resolver.dart | 1 - .../grid/cell_bloc/checkbox_cell_bloc.dart | 3 +- .../grid/cell_bloc/number_cell_bloc.dart | 66 +++++++++++++++++-- .../grid/src/widgets/cell/number_cell.dart | 44 ++++++++++++- .../grid/src/widgets/cell/text_cell.dart | 3 +- .../src/widgets/header/field_type_list.dart | 2 +- 6 files changed, 106 insertions(+), 13 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 2b37642f39..a0af57f580 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -194,7 +194,6 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (cellData, _) => NumberCellBloc( - service: CellService(), cellData: cellData, ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index ae69176fd9..a2b888a295 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -26,7 +26,7 @@ class CheckboxCellBloc extends Bloc { _startListening(); }, select: (_Selected value) async { - service.updateCell( + _service.updateCell( gridId: state.cellData.gridId, fieldId: state.cellData.field.id, rowId: state.cellData.rowId, @@ -43,6 +43,7 @@ class CheckboxCellBloc extends Bloc { @override Future close() async { + await _listener.stop(); return super.close(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index 83d2eff57d..fe5c6befeb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,4 +1,6 @@ +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -8,37 +10,87 @@ import 'cell_service.dart'; part 'number_cell_bloc.freezed.dart'; class NumberCellBloc extends Bloc { - final CellService service; + final CellService _service; + final CellListener _listener; NumberCellBloc({ - required this.service, required CellData cellData, - }) : super(NumberCellState.initial()) { + }) : _service = CellService(), + _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + super(NumberCellState.initial(cellData)) { on( (event, emit) async { await event.map( - initial: (_InitialCell value) async {}, + initial: (_Initial value) async { + _startListening(); + }, + didReceiveCellUpdate: (_DidReceiveCellUpdate value) { + emit(state.copyWith(content: value.cell.content)); + }, + updateCell: (_UpdateCell value) { + _updateCellValue(value, emit); + }, ); }, ); } + void _updateCellValue(_UpdateCell value, Emitter emit) { + final number = num.tryParse(value.text); + if (number == null) { + emit(state.copyWith(content: "")); + } else { + _service.updateCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + data: value.text, + ); + } + } + @override Future close() async { + await _listener.stop(); return super.close(); } + + void _startListening() { + _listener.updateCellNotifier.addPublishListener((result) { + result.fold( + (notificationData) async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + result.fold( + (cell) => add(NumberCellEvent.didReceiveCellUpdate(cell)), + (err) => Log.error(err), + ); + }, + (err) => Log.error(err), + ); + }); + _listener.start(); + } } @freezed class NumberCellEvent with _$NumberCellEvent { - const factory NumberCellEvent.initial() = _InitialCell; + const factory NumberCellEvent.initial() = _Initial; + const factory NumberCellEvent.updateCell(String text) = _UpdateCell; + const factory NumberCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; } @freezed class NumberCellState with _$NumberCellState { const factory NumberCellState({ - Cell? cell, + required CellData cellData, + required String content, }) = _NumberCellState; - factory NumberCellState.initial() => const NumberCellState(); + factory NumberCellState.initial(CellData cellData) { + return NumberCellState(cellData: cellData, content: cellData.cell?.content ?? ""); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index 41b8cf6ee5..ba9d75ed1b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -1,5 +1,8 @@ +import 'dart:async'; + import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -17,20 +20,44 @@ class NumberCell extends StatefulWidget { class _NumberCellState extends State { late NumberCellBloc _cellBloc; + late TextEditingController _controller; + late CellFocusNode _focusNode; + Timer? _delayOperation; @override void initState() { _cellBloc = getIt(param1: widget.cellData); + _controller = TextEditingController(text: _cellBloc.state.content); + _focusNode = CellFocusNode(); super.initState(); } @override Widget build(BuildContext context) { + _focusNode.addCallback(context, focusChanged); + return BlocProvider.value( value: _cellBloc, - child: BlocBuilder( + child: BlocConsumer( + listener: (context, state) { + if (_controller.text != state.content) { + _controller.text = state.content; + } + }, builder: (context, state) { - return Container(); + return TextField( + controller: _controller, + focusNode: _focusNode, + onChanged: (value) => focusChanged(), + onEditingComplete: () => _focusNode.unfocus(), + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + ); }, ), ); @@ -38,7 +65,20 @@ class _NumberCellState extends State { @override Future dispose() async { + _delayOperation?.cancel(); _cellBloc.close(); + _focusNode.dispose(); super.dispose(); } + + Future focusChanged() async { + if (mounted) { + _delayOperation?.cancel(); + _delayOperation = Timer(const Duration(milliseconds: 300), () { + if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) { + _cellBloc.add(NumberCellEvent.updateCell(_controller.text)); + } + }); + } + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index c7b4219bab..543a337b9b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -63,6 +63,7 @@ class _GridTextCellState extends State { @override Future dispose() async { + _delayOperation?.cancel(); _cellBloc.close(); _focusNode.dispose(); super.dispose(); @@ -72,7 +73,7 @@ class _GridTextCellState extends State { if (mounted) { _delayOperation?.cancel(); _delayOperation = Timer(const Duration(milliseconds: 300), () { - if (_cellBloc.isClosed == false) { + if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) { _cellBloc.add(TextCellEvent.updateText(_controller.text)); } }); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index 2965556f60..dfeacf4d17 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -19,7 +19,7 @@ class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate { @override Widget build(BuildContext context) { - final cells = FieldType.values.map((fieldType) { + final cells = FieldType.values.where((ty) => ty != FieldType.DateTime).map((fieldType) { return FieldTypeCell( fieldType: fieldType, onSelectField: (fieldType) { From 9073351cbb4495e67d1f28052ffe0bfdad75be6e Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 21:31:38 +0800 Subject: [PATCH 106/179] chore: disable create grid temporarily --- .../app_flowy/lib/workspace/presentation/plugins/grid/grid.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 adc2a91fa9..07fba18331 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => true; + bool get creatable => false; } class GridPlugin extends Plugin { From ef008a7b0b7050a4bbfdd97f3059422132ce540e Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 14:31:33 +0800 Subject: [PATCH 107/179] chore: fix some ui bugs --- .../presentation/plugins/grid/grid.dart | 2 +- .../widgets/cell/selection_cell/extension.dart | 5 +++-- .../cell/selection_cell/selection_editor.dart | 16 +++++++++++++--- .../grid/src/widgets/toolbar/grid_setting.dart | 13 ++++++++++--- .../lib/src/flowy_overlay/flowy_overlay.dart | 2 ++ .../lib/widget/rounded_input_field.dart | 2 +- frontend/app_flowy/pubspec.lock | 12 ++++++------ 7 files changed, 36 insertions(+), 16 deletions(-) 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 07fba18331..adc2a91fa9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => false; + bool get creatable => true; } class GridPlugin extends Plugin { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index 1b3a81704d..d3eb3b8419 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -108,6 +108,7 @@ class SelectOptionTextField extends StatelessWidget { } return TextField( + autofocus: true, controller: editController, focusNode: focusNode, onChanged: onChanged, @@ -115,8 +116,8 @@ class SelectOptionTextField extends StatelessWidget { maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: BorderSide(color: theme.shader3, width: 1.0), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: theme.main1, width: 1.0), borderRadius: Corners.s10Border, ), isDense: true, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 1df2cd03b6..5434566552 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -4,6 +4,7 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -53,7 +54,9 @@ class SelectOptionEditor extends StatelessWidget with FlowyOverlayDelegate { shrinkWrap: true, slivers: [ SliverToBoxAdapter(child: _TextField()), - const SliverToBoxAdapter(child: VSpace(10)), + const SliverToBoxAdapter(child: VSpace(6)), + const SliverToBoxAdapter(child: TypeOptionSeparator()), + const SliverToBoxAdapter(child: VSpace(6)), const SliverToBoxAdapter(child: _Title()), const SliverToBoxAdapter(child: _OptionList()), ], @@ -104,7 +107,9 @@ class _OptionList extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - final cells = state.options.map((option) => _SelectOptionCell(option)).toList(); + final cells = state.options.map((option) { + return _SelectOptionCell(option, state.selectedOptions.contains(option)); + }).toList(); final list = ListView.separated( shrinkWrap: true, controller: ScrollController(), @@ -175,7 +180,8 @@ class _Title extends StatelessWidget { class _SelectOptionCell extends StatelessWidget { final SelectOption option; - const _SelectOptionCell(this.option, {Key? key}) : super(key: key); + final bool isSelected; + const _SelectOptionCell(this.option, this.isSelected, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -194,6 +200,10 @@ class _SelectOptionCell extends StatelessWidget { const Spacer(), ]; + if (isSelected) { + children.add(svgWidget("grid/checkmark")); + } + if (onHover) { children.add(FlowyIconButton( width: 28, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart index e8a792025d..a67ddd290f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart @@ -37,10 +37,8 @@ class GridSettingList extends StatelessWidget { onAction: (action, settingContext) { switch (action) { case GridSettingAction.filter: - // TODO: Handle this case. break; case GridSettingAction.sortBy: - // TODO: Handle this case. break; case GridSettingAction.properties: GridPropertyList(gridId: settingContext.gridId, fields: settingContext.fields).show(context); @@ -130,7 +128,7 @@ class _SettingItem extends StatelessWidget { height: GridSize.typeOptionItemHeight, child: FlowyButton( isSelected: isSelected, - text: FlowyText.medium(action.title(), fontSize: 12), + text: FlowyText.medium(action.title(), fontSize: 12, color: action.enable() ? null : theme.shader4), hoverColor: theme.hover, onTap: () { context.read().add(GridSettingEvent.performAction(action)); @@ -163,4 +161,13 @@ extension _GridSettingExtension on GridSettingAction { return LocaleKeys.grid_settings_Properties.tr(); } } + + bool enable() { + switch (this) { + case GridSettingAction.properties: + return true; + default: + return false; + } + } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 1229745381..5768c52e60 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -322,7 +322,9 @@ class FlowyOverlayState extends State { // // 'app content was created above the Navigator with the WidgetsApp builder parameter.', // // ); // // ... + return MaterialApp( + theme: Theme.of(context), debugShowCheckedModeBanner: false, home: Stack( children: children..addAll(overlays), diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index 0af5e4ec89..19b3accc59 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -98,7 +98,7 @@ class _RoundedInputFieldState extends State { contentPadding: widget.contentPadding, hintText: widget.hintText, hintStyle: TextStyle(color: widget.normalBorderColor), - border: OutlineInputBorder( + enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: borderColor, width: 1.0, diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index 90e6dda24c..24b1809e2f 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -645,7 +645,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.4" + version: "0.6.3" json_annotation: dependency: transitive description: @@ -799,7 +799,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.0" path_drawing: dependency: transitive description: @@ -1133,21 +1133,21 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.20.1" + version: "1.19.5" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.8" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.11" + version: "0.4.9" textfield_tags: dependency: "direct main" description: @@ -1361,5 +1361,5 @@ packages: source: hosted version: "8.0.0" sdks: - dart: ">=2.16.0-100.0.dev <3.0.0" + dart: ">=2.15.0-116.0.dev <3.0.0" flutter: ">=2.5.0" From 7b98e8dbcaa0f87002df8a7948184e4b420b4b36 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Fri, 8 Apr 2022 14:46:20 +0800 Subject: [PATCH 108/179] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19540b8ce6..5caaed5e05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Release Notes +## Version 0.0.4 - 2022-04-08 +v0.0.4 is production ready, available on Linux, macOS, and Windows + +New features +- Grid page + ## Version 0.0.3 - 2022-02-23 v0.0.3 is production ready, available on Linux, macOS, and Windows From 1f657f3bf8302b4787e504c0548c08f62e841ce1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 15:13:53 +0800 Subject: [PATCH 109/179] fix: blockService exception --- .../lib/workspace/application/grid/grid_bloc.dart | 14 +++++++------- .../flowy-grid/src/services/grid_editor.rs | 7 ++----- 2 files changed, 9 insertions(+), 12 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 4b63ec0251..01db1f1300 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -16,12 +16,12 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final View view; final GridService service; - late GridFieldsListener _fieldListener; - late GridBlockService _blockService; - - GridBloc({required this.view, required this.service}) : super(GridState.initial()) { - _fieldListener = GridFieldsListener(gridId: view.id); + final GridFieldsListener _fieldListener; + GridBlockService? _blockService; + GridBloc({required this.view, required this.service}) + : _fieldListener = GridFieldsListener(gridId: view.id), + super(GridState.initial()) { on( (event, emit) async { await event.map( @@ -48,7 +48,7 @@ class GridBloc extends Bloc { @override Future close() async { await _fieldListener.stop(); - await _blockService.stop(); + await _blockService?.stop(); return super.close(); } @@ -70,7 +70,7 @@ class GridBloc extends Bloc { blockOrders: grid.blockOrders, ); - _blockService.blocksUpdateNotifier?.addPublishListener((result) { + _blockService?.blocksUpdateNotifier?.addPublishListener((result) { result.fold( (blockMap) => add(GridEvent.didReceiveRowUpdate(_buildRows(blockMap))), (err) => Log.error('$err'), 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 a91f0bb606..05a82d9f13 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -365,11 +365,8 @@ impl ClientGridEditor { F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { let mut write_guard = self.pad.write().await; - match f(&mut *write_guard)? { - None => {} - Some(change) => { - let _ = self.apply_change(change).await?; - } + if let Some(changeset) = f(&mut *write_guard)? { + let _ = self.apply_change(changeset).await?; } Ok(()) } From 5e686906ec029b0a6becf54aa1df14982ea2afc4 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 8 Apr 2022 15:17:54 +0800 Subject: [PATCH 110/179] Update CHANGELOG.md --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5caaed5e05..a5ac013c35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ # Release Notes -## Version 0.0.4 - 2022-04-08 -v0.0.4 is production ready, available on Linux, macOS, and Windows +## Version 0.0.4 - beta.1 - 2022-04-08 +v0.0.4 - beta.1 is pre-release New features -- Grid page +- Table-view database + - supported column types: Text, Checbox, Single-select, Multi-select, Numbers + - hide / delete columns + - insert rows ## Version 0.0.3 - 2022-02-23 v0.0.3 is production ready, available on Linux, macOS, and Windows From 6de7933a2fc2d5ee69d3535f624640f4d0e018a5 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 17:44:06 +0800 Subject: [PATCH 111/179] fix: the updated option will added to selected option list --- .../grid/cell_bloc/select_option_service.dart | 4 +- .../grid/cell_bloc/selection_editor_bloc.dart | 2 +- .../cell/selection_cell/extension.dart | 3 +- .../cell/selection_cell/selection_editor.dart | 5 +- .../flowy-grid/selection_type_option.pb.dart | 47 +++++-- .../selection_type_option.pbjson.dart | 6 +- .../rust-lib/flowy-grid/src/event_handler.rs | 5 + .../protobuf/model/selection_type_option.rs | 127 +++++++++++++++--- .../proto/selection_type_option.proto | 3 +- .../type_options/selection_type_option.rs | 6 + 10 files changed, 172 insertions(+), 36 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart index ad0a1888b3..34b977b5e3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart @@ -32,7 +32,7 @@ class SelectOptionService { ); } - Future> insert({ + Future> update({ required String gridId, required String fieldId, required String rowId, @@ -43,7 +43,7 @@ class SelectOptionService { ..fieldId = fieldId ..rowId = rowId; final payload = SelectOptionChangesetPayload.create() - ..insertOption = option + ..updateOption = option ..cellIdentifier = cellIdentifier; return GridEventApplySelectOptionChangeset(payload).send(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index e7f471dece..d2606b0fdb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -88,7 +88,7 @@ class SelectOptionEditorBloc extends Bloc children = [ - SelectOptionTag(option: option), + SelectOptionTag(option: option, isSelected: isSelected), const Spacer(), ]; @@ -206,7 +207,7 @@ class _SelectOptionCell extends StatelessWidget { if (onHover) { children.add(FlowyIconButton( - width: 28, + width: 30, onPressed: () => _showEditOptionPannel(context), iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), icon: svgWidget("editor/details", color: theme.iconColor), diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart index 5b2576d7eb..d6e0bbcdaf 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -205,6 +205,11 @@ enum SelectOptionChangesetPayload_OneOfInsertOption { notSet } +enum SelectOptionChangesetPayload_OneOfUpdateOption { + updateOption, + notSet +} + enum SelectOptionChangesetPayload_OneOfDeleteOption { deleteOption, notSet @@ -215,16 +220,22 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { 2 : SelectOptionChangesetPayload_OneOfInsertOption.insertOption, 0 : SelectOptionChangesetPayload_OneOfInsertOption.notSet }; + static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfUpdateOption> _SelectOptionChangesetPayload_OneOfUpdateOptionByTag = { + 3 : SelectOptionChangesetPayload_OneOfUpdateOption.updateOption, + 0 : SelectOptionChangesetPayload_OneOfUpdateOption.notSet + }; static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfDeleteOption> _SelectOptionChangesetPayload_OneOfDeleteOptionByTag = { - 3 : SelectOptionChangesetPayload_OneOfDeleteOption.deleteOption, + 4 : SelectOptionChangesetPayload_OneOfDeleteOption.deleteOption, 0 : SelectOptionChangesetPayload_OneOfDeleteOption.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionChangesetPayload', createEmptyInstance: create) ..oo(0, [2]) ..oo(1, [3]) + ..oo(2, [4]) ..aOM<$0.CellIdentifierPayload>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellIdentifier', subBuilder: $0.CellIdentifierPayload.create) ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOption', subBuilder: SelectOption.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOption', subBuilder: SelectOption.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updateOption', subBuilder: SelectOption.create) + ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOption', subBuilder: SelectOption.create) ..hasRequiredFields = false ; @@ -232,6 +243,7 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { factory SelectOptionChangesetPayload({ $0.CellIdentifierPayload? cellIdentifier, SelectOption? insertOption, + SelectOption? updateOption, SelectOption? deleteOption, }) { final _result = create(); @@ -241,6 +253,9 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { if (insertOption != null) { _result.insertOption = insertOption; } + if (updateOption != null) { + _result.updateOption = updateOption; + } if (deleteOption != null) { _result.deleteOption = deleteOption; } @@ -270,8 +285,11 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { SelectOptionChangesetPayload_OneOfInsertOption whichOneOfInsertOption() => _SelectOptionChangesetPayload_OneOfInsertOptionByTag[$_whichOneof(0)]!; void clearOneOfInsertOption() => clearField($_whichOneof(0)); - SelectOptionChangesetPayload_OneOfDeleteOption whichOneOfDeleteOption() => _SelectOptionChangesetPayload_OneOfDeleteOptionByTag[$_whichOneof(1)]!; - void clearOneOfDeleteOption() => clearField($_whichOneof(1)); + SelectOptionChangesetPayload_OneOfUpdateOption whichOneOfUpdateOption() => _SelectOptionChangesetPayload_OneOfUpdateOptionByTag[$_whichOneof(1)]!; + void clearOneOfUpdateOption() => clearField($_whichOneof(1)); + + SelectOptionChangesetPayload_OneOfDeleteOption whichOneOfDeleteOption() => _SelectOptionChangesetPayload_OneOfDeleteOptionByTag[$_whichOneof(2)]!; + void clearOneOfDeleteOption() => clearField($_whichOneof(2)); @$pb.TagNumber(1) $0.CellIdentifierPayload get cellIdentifier => $_getN(0); @@ -296,15 +314,26 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { SelectOption ensureInsertOption() => $_ensure(1); @$pb.TagNumber(3) - SelectOption get deleteOption => $_getN(2); + SelectOption get updateOption => $_getN(2); @$pb.TagNumber(3) - set deleteOption(SelectOption v) { setField(3, v); } + set updateOption(SelectOption v) { setField(3, v); } @$pb.TagNumber(3) - $core.bool hasDeleteOption() => $_has(2); + $core.bool hasUpdateOption() => $_has(2); @$pb.TagNumber(3) - void clearDeleteOption() => clearField(3); + void clearUpdateOption() => clearField(3); @$pb.TagNumber(3) - SelectOption ensureDeleteOption() => $_ensure(2); + SelectOption ensureUpdateOption() => $_ensure(2); + + @$pb.TagNumber(4) + SelectOption get deleteOption => $_getN(3); + @$pb.TagNumber(4) + set deleteOption(SelectOption v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasDeleteOption() => $_has(3); + @$pb.TagNumber(4) + void clearDeleteOption() => clearField(4); + @$pb.TagNumber(4) + SelectOption ensureDeleteOption() => $_ensure(3); } enum SelectOptionCellChangesetPayload_OneOfInsertOptionId { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart index 7a160d582d..9613b926bd 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -66,16 +66,18 @@ const SelectOptionChangesetPayload$json = const { '2': const [ const {'1': 'cell_identifier', '3': 1, '4': 1, '5': 11, '6': '.CellIdentifierPayload', '10': 'cellIdentifier'}, const {'1': 'insert_option', '3': 2, '4': 1, '5': 11, '6': '.SelectOption', '9': 0, '10': 'insertOption'}, - const {'1': 'delete_option', '3': 3, '4': 1, '5': 11, '6': '.SelectOption', '9': 1, '10': 'deleteOption'}, + const {'1': 'update_option', '3': 3, '4': 1, '5': 11, '6': '.SelectOption', '9': 1, '10': 'updateOption'}, + const {'1': 'delete_option', '3': 4, '4': 1, '5': 11, '6': '.SelectOption', '9': 2, '10': 'deleteOption'}, ], '8': const [ const {'1': 'one_of_insert_option'}, + const {'1': 'one_of_update_option'}, const {'1': 'one_of_delete_option'}, ], }; /// Descriptor for `SelectOptionChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEj8KD2NlbGxfaWRlbnRpZmllchgBIAEoCzIWLkNlbGxJZGVudGlmaWVyUGF5bG9hZFIOY2VsbElkZW50aWZpZXISNAoNaW5zZXJ0X29wdGlvbhgCIAEoCzINLlNlbGVjdE9wdGlvbkgAUgxpbnNlcnRPcHRpb24SNAoNZGVsZXRlX29wdGlvbhgDIAEoCzINLlNlbGVjdE9wdGlvbkgBUgxkZWxldGVPcHRpb25CFgoUb25lX29mX2luc2VydF9vcHRpb25CFgoUb25lX29mX2RlbGV0ZV9vcHRpb24='); +final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEj8KD2NlbGxfaWRlbnRpZmllchgBIAEoCzIWLkNlbGxJZGVudGlmaWVyUGF5bG9hZFIOY2VsbElkZW50aWZpZXISNAoNaW5zZXJ0X29wdGlvbhgCIAEoCzINLlNlbGVjdE9wdGlvbkgAUgxpbnNlcnRPcHRpb24SNAoNdXBkYXRlX29wdGlvbhgDIAEoCzINLlNlbGVjdE9wdGlvbkgBUgx1cGRhdGVPcHRpb24SNAoNZGVsZXRlX29wdGlvbhgEIAEoCzINLlNlbGVjdE9wdGlvbkgCUgxkZWxldGVPcHRpb25CFgoUb25lX29mX2luc2VydF9vcHRpb25CFgoUb25lX29mX3VwZGF0ZV9vcHRpb25CFgoUb25lX29mX2RlbGV0ZV9vcHRpb24='); @$core.Deprecated('Use selectOptionCellChangesetPayloadDescriptor instead') const SelectOptionCellChangesetPayload$json = const { '1': 'SelectOptionCellChangesetPayload', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index ec6dc9659e..467c3e334b 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -231,11 +231,16 @@ pub(crate) async fn select_option_changeset_handler( if let Some(mut field_meta) = editor.get_field_meta(&changeset.cell_identifier.field_id).await { let mut type_option = select_option_operation(&field_meta)?; let mut cell_data = None; + if let Some(option) = changeset.insert_option { cell_data = Some(SelectOptionCellChangeset::from_insert(&option.id).cell_data()); type_option.insert_option(option); } + if let Some(option) = changeset.update_option { + type_option.insert_option(option); + } + if let Some(option) = changeset.delete_option { cell_data = Some(SelectOptionCellChangeset::from_delete(&option.id).cell_data()); type_option.delete_option(option); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index ea45e6ac6e..fb945be12b 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -663,6 +663,7 @@ pub struct SelectOptionChangesetPayload { pub cell_identifier: ::protobuf::SingularPtrField, // message oneof groups pub one_of_insert_option: ::std::option::Option, + pub one_of_update_option: ::std::option::Option, pub one_of_delete_option: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -680,6 +681,11 @@ pub enum SelectOptionChangesetPayload_oneof_one_of_insert_option { insert_option(SelectOption), } +#[derive(Clone,PartialEq,Debug)] +pub enum SelectOptionChangesetPayload_oneof_one_of_update_option { + update_option(SelectOption), +} + #[derive(Clone,PartialEq,Debug)] pub enum SelectOptionChangesetPayload_oneof_one_of_delete_option { delete_option(SelectOption), @@ -772,7 +778,56 @@ impl SelectOptionChangesetPayload { } } - // .SelectOption delete_option = 3; + // .SelectOption update_option = 3; + + + pub fn get_update_option(&self) -> &SelectOption { + match self.one_of_update_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(ref v)) => v, + _ => ::default_instance(), + } + } + pub fn clear_update_option(&mut self) { + self.one_of_update_option = ::std::option::Option::None; + } + + pub fn has_update_option(&self) -> bool { + match self.one_of_update_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_update_option(&mut self, v: SelectOption) { + self.one_of_update_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(v)) + } + + // Mutable pointer to the field. + pub fn mut_update_option(&mut self) -> &mut SelectOption { + if let ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(_)) = self.one_of_update_option { + } else { + self.one_of_update_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(SelectOption::new())); + } + match self.one_of_update_option { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_update_option(&mut self) -> SelectOption { + if self.has_update_option() { + match self.one_of_update_option.take() { + ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(v)) => v, + _ => panic!(), + } + } else { + SelectOption::new() + } + } + + // .SelectOption delete_option = 4; pub fn get_delete_option(&self) -> &SelectOption { @@ -834,6 +889,11 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { return false; } } + if let Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(ref v)) = self.one_of_update_option { + if !v.is_initialized() { + return false; + } + } if let Some(SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v)) = self.one_of_delete_option { if !v.is_initialized() { return false; @@ -856,6 +916,12 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { self.one_of_insert_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option::insert_option(is.read_message()?)); }, 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_update_option = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(is.read_message()?)); + }, + 4 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -885,6 +951,14 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { }, }; } + if let ::std::option::Option::Some(ref v) = self.one_of_update_option { + match v { + &SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }, + }; + } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option { match v { &SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v) => { @@ -913,10 +987,19 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { }, }; } + if let ::std::option::Option::Some(ref v) = self.one_of_update_option { + match v { + &SelectOptionChangesetPayload_oneof_one_of_update_option::update_option(ref v) => { + 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 ::std::option::Option::Some(ref v) = self.one_of_delete_option { match v { &SelectOptionChangesetPayload_oneof_one_of_delete_option::delete_option(ref v) => { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }, @@ -970,6 +1053,11 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { SelectOptionChangesetPayload::has_insert_option, SelectOptionChangesetPayload::get_insert_option, )); + fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, SelectOption>( + "update_option", + SelectOptionChangesetPayload::has_update_option, + SelectOptionChangesetPayload::get_update_option, + )); fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, SelectOption>( "delete_option", SelectOptionChangesetPayload::has_delete_option, @@ -993,6 +1081,7 @@ impl ::protobuf::Clear for SelectOptionChangesetPayload { fn clear(&mut self) { self.cell_identifier.clear(); self.one_of_insert_option = ::std::option::Option::None; + self.one_of_update_option = ::std::option::Option::None; self.one_of_delete_option = ::std::option::Option::None; self.unknown_fields.clear(); } @@ -1710,24 +1799,26 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\ \x0cdisableColor\"\\\n\x0cSelectOption\x12\x0e\n\x02id\x18\x01\x20\x01(\ \tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\ - \x18\x03\x20\x01(\x0e2\x12.SelectOptionColorR\x05color\"\xfb\x01\n\x1cSe\ + \x18\x03\x20\x01(\x0e2\x12.SelectOptionColorR\x05color\"\xc9\x02\n\x1cSe\ lectOptionChangesetPayload\x12?\n\x0fcell_identifier\x18\x01\x20\x01(\ \x0b2\x16.CellIdentifierPayloadR\x0ecellIdentifier\x124\n\rinsert_option\ - \x18\x02\x20\x01(\x0b2\r.SelectOptionH\0R\x0cinsertOption\x124\n\rdelete\ - _option\x18\x03\x20\x01(\x0b2\r.SelectOptionH\x01R\x0cdeleteOptionB\x16\ - \n\x14one_of_insert_optionB\x16\n\x14one_of_delete_option\"\xfb\x01\n\ - \x20SelectOptionCellChangesetPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ - \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12*\n\x10insert_optio\ - n_id\x18\x04\x20\x01(\tH\0R\x0einsertOptionId\x12*\n\x10delete_option_id\ - \x18\x05\x20\x01(\tH\x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_opti\ - on_idB\x19\n\x17one_of_delete_option_id\"t\n\x13SelectOptionContext\x12'\ - \n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\n\ - \x0eselect_options\x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOptions*\ - y\n\x11SelectOptionColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\ - \x01\x12\r\n\tLightPink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yel\ - low\x10\x04\x12\x08\n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\ - \x04Aqua\x10\x07\x12\x08\n\x04Blue\x10\x08b\x06proto3\ + \x18\x02\x20\x01(\x0b2\r.SelectOptionH\0R\x0cinsertOption\x124\n\rupdate\ + _option\x18\x03\x20\x01(\x0b2\r.SelectOptionH\x01R\x0cupdateOption\x124\ + \n\rdelete_option\x18\x04\x20\x01(\x0b2\r.SelectOptionH\x02R\x0cdeleteOp\ + tionB\x16\n\x14one_of_insert_optionB\x16\n\x14one_of_update_optionB\x16\ + \n\x14one_of_delete_option\"\xfb\x01\n\x20SelectOptionCellChangesetPaylo\ + ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_i\ + d\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\ + \x07fieldId\x12*\n\x10insert_option_id\x18\x04\x20\x01(\tH\0R\x0einsertO\ + ptionId\x12*\n\x10delete_option_id\x18\x05\x20\x01(\tH\x01R\x0edeleteOpt\ + ionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_of_delete_option_i\ + d\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.\ + SelectOptionR\x07options\x124\n\x0eselect_options\x18\x02\x20\x03(\x0b2\ + \r.SelectOptionR\rselectOptions*y\n\x11SelectOptionColor\x12\n\n\x06Purp\ + le\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightPink\x10\x02\x12\n\n\ + \x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\n\x04Lime\x10\x05\ + \x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\x12\x08\n\x04Blue\ + \x10\x08b\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/selection_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index aee0adcd5e..9940c13e9c 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -17,7 +17,8 @@ message SelectOption { message SelectOptionChangesetPayload { CellIdentifierPayload cell_identifier = 1; oneof one_of_insert_option { SelectOption insert_option = 2; }; - oneof one_of_delete_option { SelectOption delete_option = 3; }; + oneof one_of_update_option { SelectOption update_option = 3; }; + oneof one_of_delete_option { SelectOption delete_option = 4; }; } message SelectOptionCellChangesetPayload { string grid_id = 1; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 786cd2ce0d..bcf21972ce 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -279,12 +279,16 @@ pub struct SelectOptionChangesetPayload { pub insert_option: Option, #[pb(index = 3, one_of)] + pub update_option: Option, + + #[pb(index = 4, one_of)] pub delete_option: Option, } pub struct SelectOptionChangeset { pub cell_identifier: CellIdentifier, pub insert_option: Option, + pub update_option: Option, pub delete_option: Option, } @@ -296,6 +300,7 @@ impl TryInto for SelectOptionChangesetPayload { Ok(SelectOptionChangeset { cell_identifier, insert_option: self.insert_option, + update_option: self.update_option, delete_option: self.delete_option, }) } @@ -324,6 +329,7 @@ pub struct SelectOptionCellChangesetParams { pub field_id: String, pub row_id: String, pub insert_option_id: Option, + pub delete_option_id: Option, } From a035228798e6b7020542e4c47ddf35408e64ffd1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 20:08:01 +0800 Subject: [PATCH 112/179] chore: release beta package --- .github/workflows/release.yml | 4 ++-- frontend/Makefile.toml | 2 +- frontend/scripts/makefile/flutter.toml | 32 ++++++++++++++++++-------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 69cf3ec788..93dedaa43d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,7 +66,7 @@ jobs: working-directory: frontend run: | flutter config --enable-linux-desktop - cargo make --profile production-linux-x86 appflowy + cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-linux-x86 appflowy - name: Upload Release Asset id: upload-release-asset @@ -111,7 +111,7 @@ jobs: working-directory: frontend run: | flutter config --enable-macos-desktop - cargo make --profile production-mac-x86 appflowy + cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-mac-x86 appflowy - name: Archive macOS app working-directory: ${{ env.MACOS_APP_RELEASE_PATH }} diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 4a492f4671..9cfc352d56 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -21,7 +21,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -VERSION = "0.0.3" +CURRENT_APP_VERSION = "0.0.4" FEATURES = "flutter" PRODUCT_NAME = "AppFlowy" #CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html diff --git a/frontend/scripts/makefile/flutter.toml b/frontend/scripts/makefile/flutter.toml index 8e21a4d85c..6824a60deb 100644 --- a/frontend/scripts/makefile/flutter.toml +++ b/frontend/scripts/makefile/flutter.toml @@ -5,16 +5,16 @@ linux_alias = "appflowy-linux" [tasks.appflowy-macos] dependencies = ["flowy-sdk-release"] -run_task = { name = ["code_generation", "flutter-build", "copy-to-product"] } +run_task = { name = ["code_generation", "set-app-version", "flutter-build", "copy-to-product"] } script_runner = "@shell" [tasks.appflowy-windows] dependencies = ["flowy-sdk-release"] -run_task = { name = ["code_generation", "flutter-build", "copy-to-product"] } +run_task = { name = ["code_generation", "set-app-version", "flutter-build", "copy-to-product"] } [tasks.appflowy-linux] dependencies = ["flowy-sdk-release"] -run_task = { name = ["code_generation", "flutter-build", "copy-to-product", "create-release-archive"] } +run_task = { name = ["code_generation", "set-app-version", "flutter-build", "copy-to-product", "create-release-archive"] } script_runner = "@shell" [tasks.appflowy-dev] @@ -24,16 +24,16 @@ linux_alias = "appflowy-linux-dev" [tasks.appflowy-macos-dev] dependencies = ["flowy-sdk-dev"] -run_task = { name = ["code_generation", "flutter-build", "copy-to-product"] } +run_task = { name = ["code_generation", "set-app-version", "flutter-build", "copy-to-product"] } script_runner = "@shell" [tasks.appflowy-windows-dev] dependencies = ["flowy-sdk-dev"] -run_task = { name = ["code_generation", "flutter-build", "copy-to-product"] } +run_task = { name = ["code_generation", "set-app-version", "flutter-build", "copy-to-product"] } [tasks.appflowy-linux-dev] dependencies = ["flowy-sdk-dev"] -run_task = { name = ["code_generation", "flutter-build", "copy-to-product"] } +run_task = { name = ["code_generation", "set-app-version", "flutter-build", "copy-to-product"] } script_runner = "@shell" [tasks.copy-to-product] @@ -44,7 +44,7 @@ linux_alias = "copy-to-product-linux" [tasks.copy-to-product-macos] script = [ """ - product_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${VERSION} + product_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${APP_VERSION} output_path=${product_path}/${TARGET_OS}/${FLUTTER_OUTPUT_DIR} if [ -d "${output_path}" ]; then rm -rf ${output_path}/ @@ -61,7 +61,7 @@ script_runner = "@shell" [tasks.copy-to-product-linux] script = [ """ - product_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${VERSION} + product_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${APP_VERSION} output_path=${product_path}/${TARGET_OS}/${FLUTTER_OUTPUT_DIR} if [ -d "${output_path}" ]; then rm -rf ${output_path}/ @@ -81,7 +81,7 @@ script_runner = "@shell" [tasks.copy-to-product-windows] script = [ """ - product_path= set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${VERSION} + product_path= set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${APP_VERSION} output_path= set ${product_path}/${TARGET_OS} if is_path_exists ${output_path} rm -r ${output_path}/ @@ -95,6 +95,18 @@ script = [ ] script_runner = "@duckscript" +[tasks.set-app-version] +script = [ + """ + if is_empty ${APP_VERSION} + APP_VERSION = set ${CURRENT_APP_VERSION} + set_env APP_VERSION ${CURRENT_APP_VERSION} + end + echo APP_VERSION: ${APP_VERSION} + """, +] +script_runner = "@duckscript" + # The following tasks will create an archive that will be used on the GitHub Releases section # The archives are created using different compression programs depending on the target OS # The archive will be composed of all files that are located in the /Release/AppFlowy directory @@ -129,7 +141,7 @@ script = [ cd app_flowy/ flutter clean flutter pub get - flutter build ${TARGET_OS} --${BUILD_FLAG} --build-name=${VERSION} + flutter build ${TARGET_OS} --${BUILD_FLAG} --build-name=${APP_VERSION} """, ] script_runner = "@shell" From 59fbe02ded250bd84331ec56e4add95043460cc1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 21:21:42 +0800 Subject: [PATCH 113/179] chore: rename class --- ...bloc.dart => cell_option_pannel_bloc.dart} | 22 +++++----- ...loc.dart => field_option_pannel_bloc.dart} | 28 ++++++------- .../cell/selection_cell/selection_editor.dart | 4 +- ...on_pannel.dart => cell_option_pannel.dart} | 22 +++++----- ...n_pannel.dart => field_option_pannel.dart} | 41 ++++++++++--------- .../header/type_option/multi_select.dart | 4 +- .../header/type_option/single_select.dart | 4 +- .../widgets/header/type_option/widget.dart | 9 ++-- .../flowy-grid/src/services/grid_editor.rs | 2 + 9 files changed, 70 insertions(+), 66 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/field/type_option/{edit_option_bloc.dart => cell_option_pannel_bloc.dart} (63%) rename frontend/app_flowy/lib/workspace/application/grid/field/type_option/{option_pannel_bloc.dart => field_option_pannel_bloc.dart} (60%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/{edit_option_pannel.dart => cell_option_pannel.dart} (88%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/{option_pannel.dart => field_option_pannel.dart} (83%) diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart similarity index 63% rename from frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart index ccd0c47bab..e8114b3d53 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_option_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart @@ -4,11 +4,11 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'package:protobuf/protobuf.dart'; import 'package:dartz/dartz.dart'; -part 'edit_option_bloc.freezed.dart'; +part 'cell_option_pannel_bloc.freezed.dart'; -class EditOptionBloc extends Bloc { - EditOptionBloc({required SelectOption option}) : super(EditOptionState.initial(option)) { - on( +class CellOptionPannelBloc extends Bloc { + CellOptionPannelBloc({required SelectOption option}) : super(CellOptionPannelState.initial(option)) { + on( (event, emit) async { event.map( updateName: (_UpdateName value) { @@ -46,20 +46,20 @@ class EditOptionBloc extends Bloc { } @freezed -class EditOptionEvent with _$EditOptionEvent { - const factory EditOptionEvent.updateName(String name) = _UpdateName; - const factory EditOptionEvent.updateColor(SelectOptionColor color) = _UpdateColor; - const factory EditOptionEvent.delete() = _Delete; +class CellOptionPannelEvent with _$CellOptionPannelEvent { + const factory CellOptionPannelEvent.updateName(String name) = _UpdateName; + const factory CellOptionPannelEvent.updateColor(SelectOptionColor color) = _UpdateColor; + const factory CellOptionPannelEvent.delete() = _Delete; } @freezed -class EditOptionState with _$EditOptionState { - const factory EditOptionState({ +class CellOptionPannelState with _$CellOptionPannelState { + const factory CellOptionPannelState({ required SelectOption option, required Option deleted, }) = _EditOptionState; - factory EditOptionState.initial(SelectOption option) => EditOptionState( + factory CellOptionPannelState.initial(SelectOption option) => CellOptionPannelState( option: option, deleted: none(), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/field_option_pannel_bloc.dart similarity index 60% rename from frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/type_option/field_option_pannel_bloc.dart index 715cde72d7..04ae02309d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/option_pannel_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/field_option_pannel_bloc.dart @@ -3,11 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'package:dartz/dartz.dart'; -part 'option_pannel_bloc.freezed.dart'; +part 'field_option_pannel_bloc.freezed.dart'; -class OptionPannelBloc extends Bloc { - OptionPannelBloc({required List options}) : super(OptionPannelState.initial(options)) { - on( +class FieldOptionPannelBloc extends Bloc { + FieldOptionPannelBloc({required List options}) : super(FieldOptionPannelState.initial(options)) { + on( (event, emit) async { await event.map( createOption: (_CreateOption value) async { @@ -37,25 +37,25 @@ class OptionPannelBloc extends Bloc { } @freezed -class OptionPannelEvent with _$OptionPannelEvent { - const factory OptionPannelEvent.createOption(String optionName) = _CreateOption; - const factory OptionPannelEvent.beginAddingOption() = _BeginAddingOption; - const factory OptionPannelEvent.endAddingOption() = _EndAddingOption; - const factory OptionPannelEvent.updateOption(SelectOption option) = _UpdateOption; - const factory OptionPannelEvent.deleteOption(SelectOption option) = _DeleteOption; +class FieldOptionPannelEvent with _$FieldOptionPannelEvent { + const factory FieldOptionPannelEvent.createOption(String optionName) = _CreateOption; + const factory FieldOptionPannelEvent.beginAddingOption() = _BeginAddingOption; + const factory FieldOptionPannelEvent.endAddingOption() = _EndAddingOption; + const factory FieldOptionPannelEvent.updateOption(SelectOption option) = _UpdateOption; + const factory FieldOptionPannelEvent.deleteOption(SelectOption option) = _DeleteOption; } @freezed -class OptionPannelState with _$OptionPannelState { - const factory OptionPannelState({ +class FieldOptionPannelState with _$FieldOptionPannelState { + const factory FieldOptionPannelState({ required List options, required bool isEditingOption, required Option newOptionName, required Option updateOption, required Option deleteOption, - }) = _OptionPannelState; + }) = _FieldOptionPannelState; - factory OptionPannelState.initial(List options) => OptionPannelState( + factory FieldOptionPannelState.initial(List options) => FieldOptionPannelState( options: options, isEditingOption: false, newOptionName: none(), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 12f1f514b6..dc8ffcdad1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -3,7 +3,7 @@ import 'dart:collection'; import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -225,7 +225,7 @@ class _SelectOptionCell extends StatelessWidget { } void _showEditOptionPannel(BuildContext context) { - final pannel = EditSelectOptionPannel( + final pannel = CellSelectOptionPannel( option: option, onDeleted: () { context.read().add(SelectOptionEditorEvent.deleteOption(option)); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart similarity index 88% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart index 1893a77846..9cc81a46b8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/field/type_option/edit_option_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; @@ -14,11 +14,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; -class EditSelectOptionPannel extends StatelessWidget { +class CellSelectOptionPannel extends StatelessWidget { final SelectOption option; final VoidCallback onDeleted; final Function(SelectOption) onUpdated; - const EditSelectOptionPannel({ + const CellSelectOptionPannel({ required this.option, required this.onDeleted, required this.onUpdated, @@ -28,23 +28,23 @@ class EditSelectOptionPannel extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => EditOptionBloc(option: option), + create: (context) => CellOptionPannelBloc(option: option), child: MultiBlocListener( listeners: [ - BlocListener( + BlocListener( listenWhen: (p, c) => p.deleted != c.deleted, listener: (context, state) { state.deleted.fold(() => null, (_) => onDeleted()); }, ), - BlocListener( + BlocListener( listenWhen: (p, c) => p.option != c.option, listener: (context, state) { onUpdated(state.option); }, ), ], - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { List slivers = [ SliverToBoxAdapter(child: _OptionNameTextField(state.option.name)), @@ -82,7 +82,7 @@ class _DeleteTag extends StatelessWidget { hoverColor: theme.hover, leftIcon: svgWidget("grid/delete", color: theme.iconColor), onTap: () { - context.read().add(const EditOptionEvent.delete()); + context.read().add(const CellOptionPannelEvent.delete()); }, ), ); @@ -99,7 +99,9 @@ class _OptionNameTextField extends StatelessWidget { name: name, onCanceled: () {}, onDone: (optionName) { - context.read().add(EditOptionEvent.updateName(optionName)); + if (name != optionName) { + context.read().add(CellOptionPannelEvent.updateName(optionName)); + } }, ); } @@ -178,7 +180,7 @@ class _SelectOptionColorCell extends StatelessWidget { leftIcon: colorIcon, rightIcon: checkmark, onTap: () { - context.read().add(EditOptionEvent.updateColor(color)); + context.read().add(CellOptionPannelEvent.updateColor(color)); }, ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart similarity index 83% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart index 034accfb19..7247f81a77 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/field_option_pannel_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; import 'package:flowy_infra/image.dart'; @@ -12,10 +12,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; -import 'edit_option_pannel.dart'; +import 'cell_option_pannel.dart'; import 'widget.dart'; -class OptionPannel extends StatelessWidget { +class FieldSelectOptionPannel extends StatelessWidget { final List options; final VoidCallback beginEdit; final Function(String optionName) createOptionCallback; @@ -23,7 +23,7 @@ class OptionPannel extends StatelessWidget { final Function(SelectOption) deleteOptionCallback; final TypeOptionOverlayDelegate overlayDelegate; - const OptionPannel({ + const FieldSelectOptionPannel({ required this.options, required this.beginEdit, required this.createOptionCallback, @@ -36,8 +36,8 @@ class OptionPannel extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => OptionPannelBloc(options: options), - child: BlocConsumer( + create: (context) => FieldOptionPannelBloc(options: options), + child: BlocConsumer( listener: (context, state) { if (state.isEditingOption) { beginEdit(); @@ -88,7 +88,7 @@ class OptionTitle extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); - return BlocBuilder( + return BlocBuilder( builder: (context, state) { List children = [FlowyText.medium(LocaleKeys.grid_field_optionTitle.tr(), fontSize: 12)]; if (state.options.isNotEmpty) { @@ -105,7 +105,7 @@ class OptionTitle extends StatelessWidget { ), hoverColor: theme.hover, onTap: () { - context.read().add(const OptionPannelEvent.beginAddingOption()); + context.read().add(const FieldOptionPannelEvent.beginAddingOption()); }, ), ), @@ -127,7 +127,7 @@ class _OptionList extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( buildWhen: (previous, current) { return previous.options != current.options; }, @@ -155,15 +155,15 @@ class _OptionList extends StatelessWidget { return _OptionCell( option: option, onEdited: (option) { - final pannel = EditSelectOptionPannel( + final pannel = CellSelectOptionPannel( option: option, onDeleted: () { delegate.hideOverlay(context); - context.read().add(OptionPannelEvent.deleteOption(option)); + context.read().add(FieldOptionPannelEvent.deleteOption(option)); }, onUpdated: (updatedOption) { delegate.hideOverlay(context); - context.read().add(OptionPannelEvent.updateOption(updatedOption)); + context.read().add(FieldOptionPannelEvent.updateOption(updatedOption)); }, ); delegate.showOverlay(context, pannel); @@ -208,7 +208,7 @@ class _AddOptionButton extends StatelessWidget { text: FlowyText.medium(LocaleKeys.grid_field_addSelectOption.tr(), fontSize: 12), hoverColor: theme.hover, onTap: () { - context.read().add(const OptionPannelEvent.beginAddingOption()); + context.read().add(const FieldOptionPannelEvent.beginAddingOption()); }, leftIcon: svgWidget("home/add", color: theme.iconColor), ), @@ -222,12 +222,13 @@ class _OptionNameTextField extends StatelessWidget { @override Widget build(BuildContext context) { return NameTextField( - name: "", - onCanceled: () { - context.read().add(const OptionPannelEvent.endAddingOption()); - }, - onDone: (optionName) { - context.read().add(OptionPannelEvent.createOption(optionName)); - }); + name: "", + onCanceled: () { + context.read().add(const FieldOptionPannelEvent.endAddingOption()); + }, + onDone: (optionName) { + context.read().add(FieldOptionPannelEvent.createOption(optionName)); + }, + ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 11d2c866ce..873a63ceef 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -5,7 +5,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'option_pannel.dart'; +import 'field_option_pannel.dart'; class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { final MultiSelectTypeOptionWidget _widget; @@ -48,7 +48,7 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); }, builder: (context, state) { - return OptionPannel( + return FieldSelectOptionPannel( options: state.typeOption.options, beginEdit: () { overlayDelegate.hideOverlay(context); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart index ecc0dfc80a..ba2668f851 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -4,7 +4,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'option_pannel.dart'; +import 'field_option_pannel.dart'; class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { final SingleSelectTypeOptionWidget _widget; @@ -47,7 +47,7 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget { dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); }, builder: (context, state) { - return OptionPannel( + return FieldSelectOptionPannel( options: state.typeOption.options, beginEdit: () { overlayDelegate.hideOverlay(context); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart index 6f4e86a4e1..12c1d4997b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart @@ -60,13 +60,12 @@ class _NameTextFieldState extends State { } void notifyDidEndEditing() { - if (_controller.text.isEmpty) { - if (isEdited) { + if (!_focusNode.hasFocus) { + if (_controller.text.isEmpty) { widget.onCanceled(); + } else { + widget.onDone(_controller.text); } - isEdited = true; - } else { - widget.onDone(_controller.text); } } } 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 05a82d9f13..06d7f2a1f1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -113,7 +113,9 @@ impl ClientGridEditor { } pub async fn replace_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { + let field_id = field_meta.id.clone(); let _ = self.modify(|pad| Ok(pad.replace_field(field_meta)?)).await?; + let _ = self.notify_did_update_field(&field_id).await?; Ok(()) } From fc77e0857a42f8d63b33ee433b68131342c0c665 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 21:51:06 +0800 Subject: [PATCH 114/179] fix: select option cell pannel refresh --- ...bloc.dart => edit_select_option_bloc.dart} | 24 ++++++++--------- .../cell/selection_cell/selection_cell.dart | 4 +-- .../cell/selection_cell/selection_editor.dart | 27 +++++++++---------- .../header/field_cell_action_sheet.dart | 4 +-- .../grid/src/widgets/header/field_editor.dart | 4 +-- .../src/widgets/header/type_option/date.dart | 12 ++++----- ...on_pannel.dart => edit_option_pannel.dart} | 20 +++++++------- .../type_option/field_option_pannel.dart | 5 ++-- .../widgets/header/type_option/number.dart | 6 ++--- 9 files changed, 53 insertions(+), 53 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/field/type_option/{cell_option_pannel_bloc.dart => edit_select_option_bloc.dart} (64%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/{cell_option_pannel.dart => edit_option_pannel.dart} (89%) diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_select_option_bloc.dart similarity index 64% rename from frontend/app_flowy/lib/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_select_option_bloc.dart index e8114b3d53..2854fcf199 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_select_option_bloc.dart @@ -4,11 +4,11 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'package:protobuf/protobuf.dart'; import 'package:dartz/dartz.dart'; -part 'cell_option_pannel_bloc.freezed.dart'; +part 'edit_select_option_bloc.freezed.dart'; -class CellOptionPannelBloc extends Bloc { - CellOptionPannelBloc({required SelectOption option}) : super(CellOptionPannelState.initial(option)) { - on( +class EditSelectOptionBloc extends Bloc { + EditSelectOptionBloc({required SelectOption option}) : super(EditSelectOptionState.initial(option)) { + on( (event, emit) async { event.map( updateName: (_UpdateName value) { @@ -46,20 +46,20 @@ class CellOptionPannelBloc extends Bloc deleted, - }) = _EditOptionState; + }) = _EditSelectOptionState; - factory CellOptionPannelState.initial(SelectOption option) => CellOptionPannelState( + factory EditSelectOptionState.initial(SelectOption option) => EditSelectOptionState( option: option, deleted: none(), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 3e6f5b1649..64e01bda53 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -37,7 +37,7 @@ class _SingleSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - SelectOptionEditor.show(context, state.cellData, state.options, state.selectedOptions); + SelectOptionCellEditor.show(context, state.cellData, state.options, state.selectedOptions); }, child: Row(children: children), ), @@ -86,7 +86,7 @@ class _MultiSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - SelectOptionEditor.show(context, state.cellData, state.options, state.selectedOptions); + SelectOptionCellEditor.show(context, state.cellData, state.options, state.selectedOptions); }, child: Row(children: children), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index dc8ffcdad1..b6f4001c59 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -3,7 +3,7 @@ import 'dart:collection'; import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -18,19 +18,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; -import 'package:styled_widget/styled_widget.dart'; import 'package:textfield_tags/textfield_tags.dart'; import 'extension.dart'; const double _editorPannelWidth = 300; -class SelectOptionEditor extends StatelessWidget with FlowyOverlayDelegate { +class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { final CellData cellData; final List options; final List selectedOptions; - const SelectOptionEditor({ + const SelectOptionCellEditor({ required this.cellData, required this.options, required this.selectedOptions, @@ -38,7 +37,7 @@ class SelectOptionEditor extends StatelessWidget with FlowyOverlayDelegate { }) : super(key: key); static String identifier() { - return (SelectOptionEditor).toString(); + return (SelectOptionCellEditor).toString(); } @override @@ -73,8 +72,8 @@ class SelectOptionEditor extends StatelessWidget with FlowyOverlayDelegate { List options, List selectedOptions, ) { - SelectOptionEditor.hide(context); - final editor = SelectOptionEditor( + SelectOptionCellEditor.remove(context); + final editor = SelectOptionCellEditor( cellData: cellData, options: options, selectedOptions: selectedOptions, @@ -86,14 +85,14 @@ class SelectOptionEditor extends StatelessWidget with FlowyOverlayDelegate { child: SizedBox(width: _editorPannelWidth, child: editor), constraints: BoxConstraints.loose(const Size(_editorPannelWidth, 300)), ), - identifier: SelectOptionEditor.identifier(), + identifier: SelectOptionCellEditor.identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomWithCenterAligned, delegate: editor, ); } - static void hide(BuildContext context) { + static void remove(BuildContext context) { FlowyOverlay.of(context).remove(identifier()); } @@ -208,7 +207,7 @@ class _SelectOptionCell extends StatelessWidget { if (onHover) { children.add(FlowyIconButton( width: 30, - onPressed: () => _showEditOptionPannel(context), + onPressed: () => _showEditPannel(context), iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), icon: svgWidget("editor/details", color: theme.iconColor), )); @@ -224,8 +223,8 @@ class _SelectOptionCell extends StatelessWidget { ); } - void _showEditOptionPannel(BuildContext context) { - final pannel = CellSelectOptionPannel( + void _showEditPannel(BuildContext context) { + final pannel = EditSelectOptionPannel( option: option, onDeleted: () { context.read().add(SelectOptionEditorEvent.deleteOption(option)); @@ -233,9 +232,9 @@ class _SelectOptionCell extends StatelessWidget { onUpdated: (updatedOption) { context.read().add(SelectOptionEditorEvent.updateOption(updatedOption)); }, - // key: ValueKey(option.id), + key: ValueKey(option.id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value. ); - final overlayIdentifier = pannel.toString(); + final overlayIdentifier = (EditSelectOptionPannel).toString(); FlowyOverlay.of(context).remove(overlayIdentifier); FlowyOverlay.of(context).insertWithAnchor( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart index 6cf62bf397..bebb415502 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart @@ -51,8 +51,8 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate ); } - String identifier() { - return toString(); + static String identifier() { + return (GridFieldCellActionSheet).toString(); } @override diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index 3a41ee938b..f503877a4a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -41,8 +41,8 @@ class FieldEditor extends FlowyOverlayDelegate { ); } - String identifier() { - return toString(); + static String identifier() { + return (FieldEditor).toString(); } @override diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index a31d371b09..e4365a9a1a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -114,7 +114,7 @@ class DateFormatList extends StatelessWidget { dateFormat: format, onSelected: (format) { onSelected(format); - FlowyOverlay.of(context).remove(identifier()); + FlowyOverlay.of(context).remove(DateFormatList.identifier()); }, isSelected: selectedFormat == format); }).toList(); @@ -135,8 +135,8 @@ class DateFormatList extends StatelessWidget { ); } - String identifier() { - return toString(); + static String identifier() { + return (DateFormatList).toString(); } } @@ -205,7 +205,7 @@ class TimeFormatList extends StatelessWidget { timeFormat: format, onSelected: (format) { onSelected(format); - FlowyOverlay.of(context).remove(identifier()); + FlowyOverlay.of(context).remove(TimeFormatList.identifier()); }); }).toList(); @@ -225,8 +225,8 @@ class TimeFormatList extends StatelessWidget { ); } - String identifier() { - return toString(); + static String identifier() { + return (TimeFormatList).toString(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart similarity index 89% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart index 9cc81a46b8..f8805b7180 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/cell_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/field/type_option/cell_option_pannel_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/edit_select_option_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart'; @@ -14,11 +14,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; -class CellSelectOptionPannel extends StatelessWidget { +class EditSelectOptionPannel extends StatelessWidget { final SelectOption option; final VoidCallback onDeleted; final Function(SelectOption) onUpdated; - const CellSelectOptionPannel({ + const EditSelectOptionPannel({ required this.option, required this.onDeleted, required this.onUpdated, @@ -28,23 +28,23 @@ class CellSelectOptionPannel extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => CellOptionPannelBloc(option: option), + create: (context) => EditSelectOptionBloc(option: option), child: MultiBlocListener( listeners: [ - BlocListener( + BlocListener( listenWhen: (p, c) => p.deleted != c.deleted, listener: (context, state) { state.deleted.fold(() => null, (_) => onDeleted()); }, ), - BlocListener( + BlocListener( listenWhen: (p, c) => p.option != c.option, listener: (context, state) { onUpdated(state.option); }, ), ], - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { List slivers = [ SliverToBoxAdapter(child: _OptionNameTextField(state.option.name)), @@ -82,7 +82,7 @@ class _DeleteTag extends StatelessWidget { hoverColor: theme.hover, leftIcon: svgWidget("grid/delete", color: theme.iconColor), onTap: () { - context.read().add(const CellOptionPannelEvent.delete()); + context.read().add(const EditSelectOptionEvent.delete()); }, ), ); @@ -100,7 +100,7 @@ class _OptionNameTextField extends StatelessWidget { onCanceled: () {}, onDone: (optionName) { if (name != optionName) { - context.read().add(CellOptionPannelEvent.updateName(optionName)); + context.read().add(EditSelectOptionEvent.updateName(optionName)); } }, ); @@ -180,7 +180,7 @@ class _SelectOptionColorCell extends StatelessWidget { leftIcon: colorIcon, rightIcon: checkmark, onTap: () { - context.read().add(CellOptionPannelEvent.updateColor(color)); + context.read().add(EditSelectOptionEvent.updateColor(color)); }, ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart index 7247f81a77..359d0427c9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart @@ -12,7 +12,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; -import 'cell_option_pannel.dart'; +import 'edit_option_pannel.dart'; import 'widget.dart'; class FieldSelectOptionPannel extends StatelessWidget { @@ -155,7 +155,7 @@ class _OptionList extends StatelessWidget { return _OptionCell( option: option, onEdited: (option) { - final pannel = CellSelectOptionPannel( + final pannel = EditSelectOptionPannel( option: option, onDeleted: () { delegate.hideOverlay(context); @@ -165,6 +165,7 @@ class _OptionList extends StatelessWidget { delegate.hideOverlay(context); context.read().add(FieldOptionPannelEvent.updateOption(updatedOption)); }, + key: ValueKey(option.id), ); delegate.showOverlay(context, pannel); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index a12b7e2be9..5897699442 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -81,7 +81,7 @@ class NumberFormatList extends StatelessWidget { format: format, onSelected: (format) { onSelected(format); - FlowyOverlay.of(context).remove(identifier()); + FlowyOverlay.of(context).remove(NumberFormatList.identifier()); }); }).toList(); @@ -101,8 +101,8 @@ class NumberFormatList extends StatelessWidget { ); } - String identifier() { - return toString(); + static String identifier() { + return (NumberFormatList).toString(); } } From fc4ed6c057011fa953b5e3cd962ecd280e15715b Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 8 Apr 2022 22:38:38 +0800 Subject: [PATCH 115/179] fix: grid header cell refresh after field was changed --- .../grid/field/field_cell_bloc.dart | 66 +++++++++++++++++++ .../grid/src/widgets/header/field_cell.dart | 52 +++++++++------ .../header/field_cell_action_sheet.dart | 8 +-- .../grid/src/widgets/header/grid_header.dart | 2 +- frontend/rust-lib/dart-ffi/Cargo.toml | 2 +- .../flowy-grid/src/services/grid_editor.rs | 6 +- 6 files changed, 107 insertions(+), 29 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart new file mode 100644 index 0000000000..c7964573d3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -0,0 +1,66 @@ +import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; + +part 'field_cell_bloc.freezed.dart'; + +class FieldCellBloc extends Bloc { + final FieldListener _fieldListener; + + FieldCellBloc({ + required GridFieldCellContext cellContext, + }) : _fieldListener = FieldListener(fieldId: cellContext.field.id), + super(FieldCellState.initial(cellContext)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async { + _startListening(); + }, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + emit(state.copyWith(field: value.field)); + }, + ); + }, + ); + } + + @override + Future close() async { + await _fieldListener.stop(); + return super.close(); + } + + void _startListening() { + _fieldListener.updateFieldNotifier.addPublishListener((result) { + result.fold( + (field) => add(FieldCellEvent.didReceiveFieldUpdate(field)), + (err) => Log.error(err), + ); + }); + _fieldListener.start(); + } +} + +@freezed +class FieldCellEvent with _$FieldCellEvent { + const factory FieldCellEvent.initial() = _InitialCell; + const factory FieldCellEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate; +} + +@freezed +class FieldCellState with _$FieldCellState { + const factory FieldCellState({ + required String gridId, + required Field field, + }) = _FieldCellState; + + factory FieldCellState.initial(GridFieldCellContext cellContext) => FieldCellState( + gridId: cellContext.gridId, + field: cellContext.field, + ); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index 89cd0b60ff..79e706085f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/field/field_cell_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; @@ -12,46 +13,55 @@ import 'field_cell_action_sheet.dart'; import 'field_editor.dart'; class GridFieldCell extends StatelessWidget { - final GridFieldCellContext fieldCellContext; - const GridFieldCell(this.fieldCellContext, {Key? key}) : super(key: key); + final GridFieldCellContext cellContext; + const GridFieldCell(this.cellContext, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); - final field = fieldCellContext.field; - final button = FlowyButton( - hoverColor: theme.hover, - onTap: () => _showActionSheet(context), - rightIcon: svgWidget("editor/details", color: theme.iconColor), - leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), - text: FlowyText.medium(field.name, fontSize: 12), - padding: GridSize.cellContentInsets, - ); + return BlocProvider( + create: (context) => FieldCellBloc(cellContext: cellContext)..add(const FieldCellEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + final button = FlowyButton( + hoverColor: theme.hover, + onTap: () => _showActionSheet(context), + rightIcon: svgWidget("editor/details", color: theme.iconColor), + leftIcon: svgWidget(state.field.fieldType.iconName(), color: theme.iconColor), + text: FlowyText.medium(state.field.name, fontSize: 12), + padding: GridSize.cellContentInsets, + ); - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); - return Container( - width: field.width.toDouble(), - decoration: decoration, - child: button, + return Container( + width: state.field.width.toDouble(), + decoration: decoration, + child: button, + ); + }, + ), ); } void _showActionSheet(BuildContext context) { + final state = context.read().state; GridFieldCellActionSheet( - fieldCellContext: fieldCellContext, + cellContext: GridFieldCellContext(gridId: state.gridId, field: state.field), onEdited: () => _showFieldEditor(context), ).show(context); } void _showFieldEditor(BuildContext context) { + final state = context.read().state; + FieldEditor( - gridId: fieldCellContext.gridId, + gridId: state.gridId, fieldContextLoader: FieldContextLoaderAdaptor( - gridId: fieldCellContext.gridId, - field: fieldCellContext.field, + gridId: state.gridId, + field: state.field, ), ).show(context); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart index bebb415502..42d49b69fe 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart @@ -13,9 +13,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate { - final GridFieldCellContext fieldCellContext; + final GridFieldCellContext cellContext; final VoidCallback onEdited; - const GridFieldCellActionSheet({required this.fieldCellContext, required this.onEdited, Key? key}) : super(key: key); + const GridFieldCellActionSheet({required this.cellContext, required this.onEdited, Key? key}) : super(key: key); void show(BuildContext overlayContext) { FlowyOverlay.of(overlayContext).insertWithAnchor( @@ -33,7 +33,7 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: fieldCellContext), + create: (context) => getIt(param1: cellContext), child: SingleChildScrollView( child: Column( children: [ @@ -44,7 +44,7 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate }, ), const VSpace(6), - _FieldOperationList(fieldCellContext, () => FlowyOverlay.of(context).remove(identifier())), + _FieldOperationList(cellContext, () => FlowyOverlay.of(context).remove(identifier())), ], ), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 2a7baaa773..fa5b4822d7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -58,7 +58,7 @@ class _GridHeaderDelegate extends SliverPersistentHeaderDelegate { @override bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { if (oldDelegate is _GridHeaderDelegate) { - return fields != oldDelegate.fields; + return fields.length != oldDelegate.fields.length; } return true; } diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index df26694331..143dc76b1e 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" name = "dart_ffi" # this value will change depending on the target os # default static lib -crate-type = ["staticlib"] +crate-type = ["cdylib"] [dependencies] 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 06d7f2a1f1..94f499fea1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -58,7 +58,7 @@ impl ClientGridEditor { start_field_id, grid_id, } = params; - + let field_id = field.id.clone(); let _ = self .modify(|grid| { if grid.contain_field(&field.id) { @@ -84,6 +84,7 @@ impl ClientGridEditor { }) .await?; let _ = self.notify_did_update_grid().await?; + let _ = self.notify_did_update_field(&field_id).await?; Ok(()) } @@ -409,12 +410,13 @@ impl ClientGridEditor { Ok(()) } + #[tracing::instrument(level = "trace", skip_all, err)] async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; debug_assert!(field_metas.len() == 1); if let Some(field_meta) = field_metas.pop() { - send_dart_notification(&self.grid_id, GridNotification::DidUpdateField) + send_dart_notification(&field_id, GridNotification::DidUpdateField) .payload(field_meta) .send(); } From 953af350299b7e640b6af4002107c95608b79d77 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 07:35:35 +0800 Subject: [PATCH 116/179] chore: rename struct property --- .../flowy-grid-data-model/meta.pb.dart | 93 +---- .../flowy-grid-data-model/meta.pbjson.dart | 39 +- frontend/rust-lib/dart-ffi/Cargo.toml | 2 +- .../src/services/field/field_builder.rs | 5 +- .../flowy-grid/src/services/grid_editor.rs | 2 +- .../src/services/row/row_builder.rs | 6 +- .../flowy-grid/src/services/row/row_loader.rs | 4 +- .../src/entities/meta.rs | 58 +-- .../src/protobuf/model/meta.rs | 385 ++++-------------- .../src/protobuf/proto/meta.proto | 10 +- .../src/client_grid/grid_block_meta_pad.rs | 14 +- .../src/client_grid/grid_builder.rs | 2 +- 12 files changed, 150 insertions(+), 470 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 9e730b17d2..d322e644c0 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -215,7 +215,7 @@ class FieldMeta extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionByFieldTypeId', subBuilder: TypeOptionDataByFieldTypeId.create) + ..m<$core.String, $core.String>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', entryClassName: 'FieldMeta.TypeOptionsEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OS) ..hasRequiredFields = false ; @@ -228,7 +228,7 @@ class FieldMeta extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - TypeOptionDataByFieldTypeId? typeOptionByFieldTypeId, + $core.Map<$core.String, $core.String>? typeOptions, }) { final _result = create(); if (id != null) { @@ -252,8 +252,8 @@ class FieldMeta extends $pb.GeneratedMessage { if (width != null) { _result.width = width; } - if (typeOptionByFieldTypeId != null) { - _result.typeOptionByFieldTypeId = typeOptionByFieldTypeId; + if (typeOptions != null) { + _result.typeOptions.addAll(typeOptions); } return _result; } @@ -342,56 +342,7 @@ class FieldMeta extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - TypeOptionDataByFieldTypeId get typeOptionByFieldTypeId => $_getN(7); - @$pb.TagNumber(8) - set typeOptionByFieldTypeId(TypeOptionDataByFieldTypeId v) { setField(8, v); } - @$pb.TagNumber(8) - $core.bool hasTypeOptionByFieldTypeId() => $_has(7); - @$pb.TagNumber(8) - void clearTypeOptionByFieldTypeId() => clearField(8); - @$pb.TagNumber(8) - TypeOptionDataByFieldTypeId ensureTypeOptionByFieldTypeId() => $_ensure(7); -} - -class TypeOptionDataByFieldTypeId extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TypeOptionDataByFieldTypeId', createEmptyInstance: create) - ..m<$core.String, $core.String>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'map', entryClassName: 'TypeOptionDataByFieldTypeId.MapEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OS) - ..hasRequiredFields = false - ; - - TypeOptionDataByFieldTypeId._() : super(); - factory TypeOptionDataByFieldTypeId({ - $core.Map<$core.String, $core.String>? map, - }) { - final _result = create(); - if (map != null) { - _result.map.addAll(map); - } - return _result; - } - factory TypeOptionDataByFieldTypeId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TypeOptionDataByFieldTypeId.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') - TypeOptionDataByFieldTypeId clone() => TypeOptionDataByFieldTypeId()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TypeOptionDataByFieldTypeId copyWith(void Function(TypeOptionDataByFieldTypeId) updates) => super.copyWith((message) => updates(message as TypeOptionDataByFieldTypeId)) as TypeOptionDataByFieldTypeId; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TypeOptionDataByFieldTypeId create() => TypeOptionDataByFieldTypeId._(); - TypeOptionDataByFieldTypeId createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static TypeOptionDataByFieldTypeId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static TypeOptionDataByFieldTypeId? _defaultInstance; - - @$pb.TagNumber(1) - $core.Map<$core.String, $core.String> get map => $_getMap(0); + $core.Map<$core.String, $core.String> get typeOptions => $_getMap(7); } enum FieldChangesetPayload_OneOfName { @@ -709,7 +660,7 @@ class RowMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMeta.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) + ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cells', entryClassName: 'RowMeta.CellsEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..hasRequiredFields = false @@ -719,7 +670,7 @@ class RowMeta extends $pb.GeneratedMessage { factory RowMeta({ $core.String? id, $core.String? blockId, - $core.Map<$core.String, CellMeta>? cellByFieldId, + $core.Map<$core.String, CellMeta>? cells, $core.int? height, $core.bool? visibility, }) { @@ -730,8 +681,8 @@ class RowMeta extends $pb.GeneratedMessage { if (blockId != null) { _result.blockId = blockId; } - if (cellByFieldId != null) { - _result.cellByFieldId.addAll(cellByFieldId); + if (cells != null) { + _result.cells.addAll(cells); } if (height != null) { _result.height = height; @@ -781,7 +732,7 @@ class RowMeta extends $pb.GeneratedMessage { void clearBlockId() => clearField(2); @$pb.TagNumber(3) - $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(2); + $core.Map<$core.String, CellMeta> get cells => $_getMap(2); @$pb.TagNumber(4) $core.int get height => $_getIZ(3); @@ -913,20 +864,15 @@ class RowMetaChangeset extends $pb.GeneratedMessage { class CellMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; CellMeta._() : super(); factory CellMeta({ - $core.String? fieldId, $core.String? data, }) { final _result = create(); - if (fieldId != null) { - _result.fieldId = fieldId; - } if (data != null) { _result.data = data; } @@ -954,22 +900,13 @@ class CellMeta extends $pb.GeneratedMessage { static CellMeta? _defaultInstance; @$pb.TagNumber(1) - $core.String get fieldId => $_getSZ(0); + $core.String get data => $_getSZ(0); @$pb.TagNumber(1) - set fieldId($core.String v) { $_setString(0, v); } + set data($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasFieldId() => $_has(0); + $core.bool hasData() => $_has(0); @$pb.TagNumber(1) - void clearFieldId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get data => $_getSZ(1); - @$pb.TagNumber(2) - set data($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasData() => $_has(1); - @$pb.TagNumber(2) - void clearData() => clearField(2); + void clearData() => clearField(1); } enum CellMetaChangeset_OneOfData { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 65e813160f..71b0c1b8e0 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -69,24 +69,14 @@ const FieldMeta$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_option_by_field_type_id', '3': 8, '4': 1, '5': 11, '6': '.TypeOptionDataByFieldTypeId', '10': 'typeOptionByFieldTypeId'}, + const {'1': 'type_options', '3': 8, '4': 3, '5': 11, '6': '.FieldMeta.TypeOptionsEntry', '10': 'typeOptions'}, ], + '3': const [FieldMeta_TypeOptionsEntry$json], }; -/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSWwocdHlwZV9vcHRpb25fYnlfZmllbGRfdHlwZV9pZBgIIAEoCzIcLlR5cGVPcHRpb25EYXRhQnlGaWVsZFR5cGVJZFIXdHlwZU9wdGlvbkJ5RmllbGRUeXBlSWQ='); -@$core.Deprecated('Use typeOptionDataByFieldTypeIdDescriptor instead') -const TypeOptionDataByFieldTypeId$json = const { - '1': 'TypeOptionDataByFieldTypeId', - '2': const [ - const {'1': 'map', '3': 1, '4': 3, '5': 11, '6': '.TypeOptionDataByFieldTypeId.MapEntry', '10': 'map'}, - ], - '3': const [TypeOptionDataByFieldTypeId_MapEntry$json], -}; - -@$core.Deprecated('Use typeOptionDataByFieldTypeIdDescriptor instead') -const TypeOptionDataByFieldTypeId_MapEntry$json = const { - '1': 'MapEntry', +@$core.Deprecated('Use fieldMetaDescriptor instead') +const FieldMeta_TypeOptionsEntry$json = const { + '1': 'TypeOptionsEntry', '2': const [ const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'}, @@ -94,8 +84,8 @@ const TypeOptionDataByFieldTypeId_MapEntry$json = const { '7': const {'7': true}, }; -/// Descriptor for `TypeOptionDataByFieldTypeId`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List typeOptionDataByFieldTypeIdDescriptor = $convert.base64Decode('ChtUeXBlT3B0aW9uRGF0YUJ5RmllbGRUeXBlSWQSNwoDbWFwGAEgAygLMiUuVHlwZU9wdGlvbkRhdGFCeUZpZWxkVHlwZUlkLk1hcEVudHJ5UgNtYXAaNgoITWFwRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4AQ=='); +/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSPgoMdHlwZV9vcHRpb25zGAggAygLMhsuRmllbGRNZXRhLlR5cGVPcHRpb25zRW50cnlSC3R5cGVPcHRpb25zGj4KEFR5cGVPcHRpb25zRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4AQ=='); @$core.Deprecated('Use fieldChangesetPayloadDescriptor instead') const FieldChangesetPayload$json = const { '1': 'FieldChangesetPayload', @@ -140,16 +130,16 @@ const RowMeta$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'cells', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellsEntry', '10': 'cells'}, const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'}, ], - '3': const [RowMeta_CellByFieldIdEntry$json], + '3': const [RowMeta_CellsEntry$json], }; @$core.Deprecated('Use rowMetaDescriptor instead') -const RowMeta_CellByFieldIdEntry$json = const { - '1': 'CellByFieldIdEntry', +const RowMeta_CellsEntry$json = const { + '1': 'CellsEntry', '2': const [ const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, @@ -158,7 +148,7 @@ const RowMeta_CellByFieldIdEntry$json = const { }; /// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIZCghibG9ja19pZBgCIAEoCVIHYmxvY2tJZBJEChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhsuUm93TWV0YS5DZWxsQnlGaWVsZElkRW50cnlSDWNlbGxCeUZpZWxkSWQSFgoGaGVpZ2h0GAQgASgFUgZoZWlnaHQSHgoKdmlzaWJpbGl0eRgFIAEoCFIKdmlzaWJpbGl0eRpLChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHwoFdmFsdWUYAiABKAsyCS5DZWxsTWV0YVIFdmFsdWU6AjgB'); +final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIZCghibG9ja19pZBgCIAEoCVIHYmxvY2tJZBIpCgVjZWxscxgDIAMoCzITLlJvd01ldGEuQ2VsbHNFbnRyeVIFY2VsbHMSFgoGaGVpZ2h0GAQgASgFUgZoZWlnaHQSHgoKdmlzaWJpbGl0eRgFIAEoCFIKdmlzaWJpbGl0eRpDCgpDZWxsc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); @$core.Deprecated('Use rowMetaChangesetDescriptor instead') const RowMetaChangeset$json = const { '1': 'RowMetaChangeset', @@ -191,13 +181,12 @@ final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode(' const CellMeta$json = const { '1': 'CellMeta', '2': const [ - const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 2, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 1, '4': 1, '5': 9, '10': 'data'}, ], }; /// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBISCgRkYXRhGAIgASgJUgRkYXRh'); +final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRISCgRkYXRhGAEgASgJUgRkYXRh'); @$core.Deprecated('Use cellMetaChangesetDescriptor instead') const CellMetaChangeset$json = const { '1': 'CellMetaChangeset', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 143dc76b1e..df26694331 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" name = "dart_ffi" # this value will change depending on the target os # default static lib -crate-type = ["cdylib"] +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 9a654d4c43..d18e6aa07f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,6 +1,7 @@ use crate::services::field::type_options::*; use bytes::Bytes; -use flowy_grid_data_model::entities::{Field, FieldMeta, FieldType, TypeOptionDataByFieldTypeId, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{Field, FieldMeta, FieldType, TypeOptionDataEntry}; +use std::collections::HashMap; pub struct FieldBuilder { field_meta: FieldMeta, @@ -33,7 +34,7 @@ impl FieldBuilder { frozen: field.frozen, visibility: field.visibility, width: field.width, - type_option_by_field_type_id: TypeOptionDataByFieldTypeId::default(), + type_options: HashMap::default(), }; Self { field_meta, diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 94f499fea1..b934d4bc35 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -279,7 +279,7 @@ impl ClientGridEditor { match row_meta { None => Ok(None), Some(row_meta) => { - let cell_meta = row_meta.cell_by_field_id.get(field_id).cloned(); + let cell_meta = row_meta.cells.get(field_id).cloned(); Ok(cell_meta) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 0a0da4df57..2e6970d2c9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -38,7 +38,7 @@ impl<'a> CreateRowMetaBuilder<'a> { } Some(field_meta) => { let data = apply_cell_data_changeset(&data, None, field_meta)?; - let cell = CellMeta::new(field_id, data); + let cell = CellMeta::new(data); self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); Ok(()) } @@ -54,7 +54,7 @@ impl<'a> CreateRowMetaBuilder<'a> { Some(field_meta) => { let cell_data = SelectOptionCellChangeset::from_insert(&data).cell_data(); let data = apply_cell_data_changeset(&cell_data, None, field_meta)?; - let cell = CellMeta::new(field_id, data); + let cell = CellMeta::new(data); self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); Ok(()) } @@ -82,7 +82,7 @@ pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload) RowMeta { id: payload.row_id, block_id: block_id.to_owned(), - cell_by_field_id: payload.cell_by_field_id, + cells: payload.cell_by_field_id, height: payload.height, visibility: payload.visibility, } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index b37d937c0f..89f7db216c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -61,7 +61,7 @@ pub fn make_cell_by_field_id( #[allow(dead_code)] pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { - let cell_meta = row_meta.cell_by_field_id.get(field_id)?.clone(); + let cell_meta = row_meta.cells.get(field_id)?.clone(); match decode_cell_data(cell_meta.data, field_meta) { Ok(content) => Some(Cell::new(field_id, content)), Err(e) => { @@ -83,7 +83,7 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc| { let cell_by_field_id = row_meta - .cell_by_field_id + .cells .clone() .into_par_iter() .flat_map(|(field_id, cell_meta)| make_cell_by_field_id(&field_meta_map, field_id, cell_meta)) diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index cf48a70823..a170e9c4d4 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -101,7 +101,10 @@ pub struct FieldMeta { pub width: i32, #[pb(index = 8)] - pub type_option_by_field_type_id: TypeOptionDataByFieldTypeId, + /// type_options contains key/value pairs + /// key: id of the FieldType + /// value: type option data string + pub type_options: HashMap, } impl FieldMeta { @@ -114,31 +117,28 @@ impl FieldMeta { frozen: false, visibility: true, width: DEFAULT_FIELD_WIDTH, - type_option_by_field_type_id: Default::default(), + type_options: Default::default(), } } pub fn insert_type_option_entry(&mut self, entry: &T) { - self.type_option_by_field_type_id - .insert(entry.field_type().type_id(), entry.json_str()); + self.type_options.insert(entry.field_type().type_id(), entry.json_str()); } pub fn get_type_option_entry(&self, field_type: Option) -> Option { let field_type = field_type.as_ref().unwrap_or(&self.field_type); - self.type_option_by_field_type_id + self.type_options .get(&field_type.type_id()) .map(|s| T::from_json_str(s)) } pub fn insert_type_option_str(&mut self, field_type: &FieldType, json_str: String) { - self.type_option_by_field_type_id.insert(field_type.type_id(), json_str); + self.type_options.insert(field_type.type_id(), json_str); } pub fn get_type_option_str(&self, field_type: Option) -> Option { let field_type = field_type.as_ref().unwrap_or(&self.field_type); - self.type_option_by_field_type_id - .get(&field_type.type_id()) - .map(|s| s.to_owned()) + self.type_options.get(&field_type.type_id()).map(|s| s.to_owned()) } } @@ -153,26 +153,6 @@ pub trait TypeOptionDataEntity { fn from_protobuf_bytes(bytes: Bytes) -> Self; } -#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf, PartialEq, Eq)] -pub struct TypeOptionDataByFieldTypeId { - #[pb(index = 1)] - pub map: HashMap, -} - -impl std::ops::Deref for TypeOptionDataByFieldTypeId { - type Target = HashMap; - - fn deref(&self) -> &Self::Target { - &self.map - } -} - -impl std::ops::DerefMut for TypeOptionDataByFieldTypeId { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.map - } -} - #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldChangesetPayload { #[pb(index = 1)] @@ -321,7 +301,10 @@ pub struct RowMeta { pub block_id: String, #[pb(index = 3)] - pub cell_by_field_id: HashMap, + /// cells contains key/value pairs. + /// key: field id, + /// value: CellMeta + pub cells: HashMap, #[pb(index = 4)] pub height: i32, @@ -335,7 +318,7 @@ impl RowMeta { Self { id: uuid::Uuid::new_v4().to_string(), block_id: block_id.to_owned(), - cell_by_field_id: Default::default(), + cells: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, } @@ -360,18 +343,12 @@ pub struct RowMetaChangeset { #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct CellMeta { #[pb(index = 1)] - pub field_id: String, - - #[pb(index = 2)] pub data: String, } impl CellMeta { - pub fn new(field_id: &str, data: String) -> Self { - Self { - field_id: field_id.to_string(), - data, - } + pub fn new(data: String) -> Self { + Self { data } } } @@ -395,7 +372,6 @@ impl std::convert::From for RowMetaChangeset { let mut cell_by_field_id = HashMap::with_capacity(1); let field_id = changeset.field_id; let cell_meta = CellMeta { - field_id: field_id.clone(), data: changeset.data.unwrap_or_else(|| "".to_owned()), }; cell_by_field_id.insert(field_id, cell_meta); @@ -404,7 +380,7 @@ impl std::convert::From for RowMetaChangeset { row_id: changeset.row_id, height: None, visibility: None, - cell_by_field_id, + cell_by_field_id: cell_by_field_id, } } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 97e14eb738..f90832a447 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -727,7 +727,7 @@ pub struct FieldMeta { pub frozen: bool, pub visibility: bool, pub width: i32, - pub type_option_by_field_type_id: ::protobuf::SingularPtrField, + pub type_options: ::std::collections::HashMap<::std::string::String, ::std::string::String>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -882,47 +882,34 @@ impl FieldMeta { self.width = v; } - // .TypeOptionDataByFieldTypeId type_option_by_field_type_id = 8; + // repeated .FieldMeta.TypeOptionsEntry type_options = 8; - pub fn get_type_option_by_field_type_id(&self) -> &TypeOptionDataByFieldTypeId { - self.type_option_by_field_type_id.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_type_options(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { + &self.type_options } - pub fn clear_type_option_by_field_type_id(&mut self) { - self.type_option_by_field_type_id.clear(); - } - - pub fn has_type_option_by_field_type_id(&self) -> bool { - self.type_option_by_field_type_id.is_some() + pub fn clear_type_options(&mut self) { + self.type_options.clear(); } // Param is passed by value, moved - pub fn set_type_option_by_field_type_id(&mut self, v: TypeOptionDataByFieldTypeId) { - self.type_option_by_field_type_id = ::protobuf::SingularPtrField::some(v); + pub fn set_type_options(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { + self.type_options = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_type_option_by_field_type_id(&mut self) -> &mut TypeOptionDataByFieldTypeId { - if self.type_option_by_field_type_id.is_none() { - self.type_option_by_field_type_id.set_default(); - } - self.type_option_by_field_type_id.as_mut().unwrap() + pub fn mut_type_options(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { + &mut self.type_options } // Take field - pub fn take_type_option_by_field_type_id(&mut self) -> TypeOptionDataByFieldTypeId { - self.type_option_by_field_type_id.take().unwrap_or_else(|| TypeOptionDataByFieldTypeId::new()) + pub fn take_type_options(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { + ::std::mem::replace(&mut self.type_options, ::std::collections::HashMap::new()) } } impl ::protobuf::Message for FieldMeta { fn is_initialized(&self) -> bool { - for v in &self.type_option_by_field_type_id { - if !v.is_initialized() { - return false; - } - }; true } @@ -964,7 +951,7 @@ impl ::protobuf::Message for FieldMeta { self.width = tmp; }, 8 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_option_by_field_type_id)?; + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.type_options)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -999,10 +986,7 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } - if let Some(ref v) = self.type_option_by_field_type_id.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(8, &self.type_options); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -1030,11 +1014,7 @@ impl ::protobuf::Message for FieldMeta { if self.width != 0 { os.write_int32(7, self.width)?; } - if let Some(ref v) = self.type_option_by_field_type_id.as_ref() { - os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(8, &self.type_options, os)?; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -1108,10 +1088,10 @@ impl ::protobuf::Message for FieldMeta { |m: &FieldMeta| { &m.width }, |m: &mut FieldMeta| { &mut m.width }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "type_option_by_field_type_id", - |m: &FieldMeta| { &m.type_option_by_field_type_id }, - |m: &mut FieldMeta| { &mut m.type_option_by_field_type_id }, + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( + "type_options", + |m: &FieldMeta| { &m.type_options }, + |m: &mut FieldMeta| { &mut m.type_options }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldMeta", @@ -1136,7 +1116,7 @@ impl ::protobuf::Clear for FieldMeta { self.frozen = false; self.visibility = false; self.width = 0; - self.type_option_by_field_type_id.clear(); + self.type_options.clear(); self.unknown_fields.clear(); } } @@ -1153,160 +1133,6 @@ impl ::protobuf::reflect::ProtobufValue for FieldMeta { } } -#[derive(PartialEq,Clone,Default)] -pub struct TypeOptionDataByFieldTypeId { - // message fields - pub map: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a TypeOptionDataByFieldTypeId { - fn default() -> &'a TypeOptionDataByFieldTypeId { - ::default_instance() - } -} - -impl TypeOptionDataByFieldTypeId { - pub fn new() -> TypeOptionDataByFieldTypeId { - ::std::default::Default::default() - } - - // repeated .TypeOptionDataByFieldTypeId.MapEntry map = 1; - - - pub fn get_map(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.map - } - pub fn clear_map(&mut self) { - self.map.clear(); - } - - // Param is passed by value, moved - pub fn set_map(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { - self.map = v; - } - - // Mutable pointer to the field. - pub fn mut_map(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.map - } - - // Take field - pub fn take_map(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { - ::std::mem::replace(&mut self.map, ::std::collections::HashMap::new()) - } -} - -impl ::protobuf::Message for TypeOptionDataByFieldTypeId { - 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_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.map)?; - }, - _ => { - ::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; - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.map); - 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<()> { - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.map, 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() -> TypeOptionDataByFieldTypeId { - TypeOptionDataByFieldTypeId::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_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( - "map", - |m: &TypeOptionDataByFieldTypeId| { &m.map }, - |m: &mut TypeOptionDataByFieldTypeId| { &mut m.map }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "TypeOptionDataByFieldTypeId", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static TypeOptionDataByFieldTypeId { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(TypeOptionDataByFieldTypeId::new) - } -} - -impl ::protobuf::Clear for TypeOptionDataByFieldTypeId { - fn clear(&mut self) { - self.map.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for TypeOptionDataByFieldTypeId { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for TypeOptionDataByFieldTypeId { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldChangesetPayload { // message fields @@ -2186,7 +2012,7 @@ pub struct RowMeta { // message fields pub id: ::std::string::String, pub block_id: ::std::string::String, - pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, + pub cells: ::std::collections::HashMap<::std::string::String, CellMeta>, pub height: i32, pub visibility: bool, // special fields @@ -2257,29 +2083,29 @@ impl RowMeta { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .RowMeta.CellByFieldIdEntry cell_by_field_id = 3; + // repeated .RowMeta.CellsEntry cells = 3; - pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { - &self.cell_by_field_id + pub fn get_cells(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { + &self.cells } - pub fn clear_cell_by_field_id(&mut self) { - self.cell_by_field_id.clear(); + pub fn clear_cells(&mut self) { + self.cells.clear(); } // Param is passed by value, moved - pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { - self.cell_by_field_id = v; + pub fn set_cells(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { + self.cells = v; } // Mutable pointer to the field. - pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { - &mut self.cell_by_field_id + pub fn mut_cells(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { + &mut self.cells } // Take field - pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { - ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) + pub fn take_cells(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { + ::std::mem::replace(&mut self.cells, ::std::collections::HashMap::new()) } // int32 height = 4; @@ -2329,7 +2155,7 @@ impl ::protobuf::Message for RowMeta { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 3 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cells)?; }, 4 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -2363,7 +2189,7 @@ impl ::protobuf::Message for RowMeta { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.block_id); } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cells); if self.height != 0 { my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); } @@ -2382,7 +2208,7 @@ impl ::protobuf::Message for RowMeta { if !self.block_id.is_empty() { os.write_string(2, &self.block_id)?; } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cells, os)?; if self.height != 0 { os.write_int32(4, self.height)?; } @@ -2438,9 +2264,9 @@ impl ::protobuf::Message for RowMeta { |m: &mut RowMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "cell_by_field_id", - |m: &RowMeta| { &m.cell_by_field_id }, - |m: &mut RowMeta| { &mut m.cell_by_field_id }, + "cells", + |m: &RowMeta| { &m.cells }, + |m: &mut RowMeta| { &mut m.cells }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "height", @@ -2470,7 +2296,7 @@ impl ::protobuf::Clear for RowMeta { fn clear(&mut self) { self.id.clear(); self.block_id.clear(); - self.cell_by_field_id.clear(); + self.cells.clear(); self.height = 0; self.visibility = false; self.unknown_fields.clear(); @@ -2803,7 +2629,6 @@ impl ::protobuf::reflect::ProtobufValue for RowMetaChangeset { #[derive(PartialEq,Clone,Default)] pub struct CellMeta { // message fields - pub field_id: ::std::string::String, pub data: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -2821,33 +2646,7 @@ impl CellMeta { ::std::default::Default::default() } - // string field_id = 1; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string data = 2; + // string data = 1; pub fn get_data(&self) -> &str { @@ -2884,9 +2683,6 @@ impl ::protobuf::Message for CellMeta { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; }, _ => { @@ -2901,11 +2697,8 @@ impl ::protobuf::Message for CellMeta { #[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.data.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.data); + my_size += ::protobuf::rt::string_size(1, &self.data); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2913,11 +2706,8 @@ impl ::protobuf::Message for CellMeta { } 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.data.is_empty() { - os.write_string(2, &self.data)?; + os.write_string(1, &self.data)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2957,11 +2747,6 @@ impl ::protobuf::Message for CellMeta { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &CellMeta| { &m.field_id }, - |m: &mut CellMeta| { &mut m.field_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "data", |m: &CellMeta| { &m.data }, @@ -2983,7 +2768,6 @@ impl ::protobuf::Message for CellMeta { impl ::protobuf::Clear for CellMeta { fn clear(&mut self) { - self.field_id.clear(); self.data.clear(); self.unknown_fields.clear(); } @@ -3676,55 +3460,52 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMet\ aData\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_m\ - etas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\x99\x02\n\tFieldMe\ + etas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xbc\x02\n\tFieldMe\ ta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ - idth\x12[\n\x1ctype_option_by_field_type_id\x18\x08\x20\x01(\x0b2\x1c.Ty\ - peOptionDataByFieldTypeIdR\x17typeOptionByFieldTypeId\"\x8e\x01\n\x1bTyp\ - eOptionDataByFieldTypeId\x127\n\x03map\x18\x01\x20\x03(\x0b2%.TypeOption\ - DataByFieldTypeId.MapEntryR\x03map\x1a6\n\x08MapEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05va\ - lue:\x028\x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\ - \x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\ - \x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\ - \x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\ - \x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\ - \x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\ - \x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\ - \r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\ - \n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\ - \x19\n\x17one_of_type_option_data\"8\n\x07AnyData\x12\x17\n\x07type_id\ - \x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\ - \x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ - id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_b\ - y_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellBy\ - FieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nv\ - isibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\ - \x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\ - \x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChan\ - geset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06heig\ - ht\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\ - \x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\ - \x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12Cel\ - lByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ - \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\ro\ - ne_of_heightB\x13\n\x11one_of_visibility\"9\n\x08CellMeta\x12\x19\n\x08f\ - ield_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01\ - (\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05ro\ - wId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04da\ - ta\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\"\xac\x01\n\x10Bui\ - ldGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\n\ - fieldMetas\x12/\n\x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMeta\ - R\nblockMetas\x12:\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBl\ - ockMetaDataR\rblockMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\ - \x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSi\ - ngleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbo\ - x\x10\x05b\x06proto3\ + idth\x12>\n\x0ctype_options\x18\x08\x20\x03(\x0b2\x1b.FieldMeta.TypeOpti\ + onsEntryR\x0btypeOptions\x1a>\n\x10TypeOptionsEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\ + \x028\x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\ + \x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06\ + gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04des\ + c\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\ + \x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\ + \x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nv\ + isibility\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\ + \x10type_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0b\ + one_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_\ + of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17o\ + ne_of_type_option_data\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\ + \x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\ + \xdc\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\ + \n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12)\n\x05cells\x18\x03\ + \x20\x03(\x0b2\x13.RowMeta.CellsEntryR\x05cells\x12\x16\n\x06height\x18\ + \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ + \nvisibility\x1aC\n\nCellsEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03\ + key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\ + \x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01\ + (\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\ + \x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell\ + _by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\ + \rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ + \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ + \x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\ + \x1e\n\x08CellMeta\x12\x12\n\x04data\x18\x01\x20\x01(\tR\x04data\"\x83\ + \x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06\ + gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ + ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\ + \tH\0R\x04dataB\r\n\x0bone_of_data\"\xac\x01\n\x10BuildGridContext\x12+\ + \n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\ + \x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12\ + :\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\rblo\ + ckMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ + \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ + \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ + o3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index ca00b88b57..18c05896fe 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -22,10 +22,7 @@ message FieldMeta { bool frozen = 5; bool visibility = 6; int32 width = 7; - TypeOptionDataByFieldTypeId type_option_by_field_type_id = 8; -} -message TypeOptionDataByFieldTypeId { - map map = 1; + map type_options = 8; } message FieldChangesetPayload { string field_id = 1; @@ -45,7 +42,7 @@ message AnyData { message RowMeta { string id = 1; string block_id = 2; - map cell_by_field_id = 3; + map cells = 3; int32 height = 4; bool visibility = 5; } @@ -56,8 +53,7 @@ message RowMetaChangeset { map cell_by_field_id = 4; } message CellMeta { - string field_id = 1; - string data = 2; + string data = 1; } message CellMetaChangeset { string grid_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 688b32cccc..2d70309fef 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -24,9 +24,9 @@ pub struct GridBlockMetaPad { impl GridBlockMetaPad { pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - tracing::trace!("{}", s); let meta_data: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { let msg = format!("Deserialize delta to block meta failed: {}", e); + tracing::error!("{}", s); CollaborateError::internal().context(msg) })?; let block_id = meta_data.block_id; @@ -107,7 +107,7 @@ impl GridBlockMetaPad { let cell_metas = rows .iter() .flat_map(|row| { - let cell_meta = row.cell_by_field_id.get(field_id)?; + let cell_meta = row.cells.get(field_id)?; Some(cell_meta.clone()) }) .collect::>(); @@ -135,7 +135,7 @@ impl GridBlockMetaPad { if !changeset.cell_by_field_id.is_empty() { is_changed = Some(()); changeset.cell_by_field_id.into_iter().for_each(|(field_id, cell)| { - row.cell_by_field_id.insert(field_id, cell); + row.cells.insert(field_id, cell); }) } @@ -237,7 +237,7 @@ mod tests { let row = RowMeta { id: "1".to_string(), block_id: pad.block_id.clone(), - cell_by_field_id: Default::default(), + cells: Default::default(), height: 0, visibility: false, }; @@ -283,7 +283,7 @@ mod tests { RowMeta { id: id.to_string(), block_id: pad.block_id.clone(), - cell_by_field_id: Default::default(), + cells: Default::default(), height: 0, visibility: false, } @@ -328,7 +328,7 @@ mod tests { let row = RowMeta { id: "1".to_string(), block_id: pad.block_id.clone(), - cell_by_field_id: Default::default(), + cells: Default::default(), height: 0, visibility: false, }; @@ -349,7 +349,7 @@ mod tests { let row = RowMeta { id: "1".to_string(), block_id: pad.block_id.clone(), - cell_by_field_id: Default::default(), + cells: Default::default(), height: 0, visibility: false, }; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs index 2b91e1352c..43b85de269 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs @@ -28,7 +28,7 @@ impl GridBuilder { fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); for row in rows { - let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); + let cell_field_ids = row.cells.keys().into_iter().collect::>(); if cell_field_ids != field_ids { let msg = format!("{:?} contains invalid cells", row); return Err(CollaborateError::internal().context(msg)); From 0ba0bb62ce02bcf488c582a6e3dc2a4938b0382c Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 11:55:00 +0800 Subject: [PATCH 117/179] chore: config flowy-sync crate log level --- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-sdk/src/lib.rs | 3 +-- shared-lib/Cargo.lock | 1 + shared-lib/flowy-grid-data-model/Cargo.toml | 1 + .../flowy-grid-data-model/src/entities/meta.rs | 13 ++++++++++++- .../src/client_grid/grid_block_meta_pad.rs | 1 + 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 1a996b2a43..a21105a163 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -975,6 +975,7 @@ dependencies = [ "protobuf", "serde", "serde_json", + "serde_repr", "strum", "strum_macros", "uuid", diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 8ade107e00..6ae356346c 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -74,12 +74,11 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("lib_ot={}", level)); filters.push(format!("lib_ws={}", level)); filters.push(format!("lib_infra={}", level)); + filters.push(format!("flowy_sync={}", level)); filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_database={}", "info")); filters.push(format!("flowy_net={}", "info")); - filters.push(format!("flowy_sync={}", "info")); - filters.join(",") } diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index db2a3d9ad7..52cb6d081f 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -462,6 +462,7 @@ dependencies = [ "protobuf", "serde", "serde_json", + "serde_repr", "strum", "strum_macros", "uuid", diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index 89461b444c..e5a78e41ca 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -13,6 +13,7 @@ strum = "0.21" strum_macros = "0.21" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} +serde_repr = "0.1" uuid = { version = "0.8", features = ["serde", "v4"] } flowy-error-code = { path = "../flowy-error-code"} diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index a170e9c4d4..2178a49f24 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -3,6 +3,7 @@ use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; use serde::{Deserialize, Serialize}; +use serde_repr::*; use std::collections::HashMap; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; @@ -224,7 +225,17 @@ impl TryInto for FieldChangesetPayload { } #[derive( - Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize, + Debug, + Clone, + PartialEq, + Eq, + ProtoBuf_Enum, + EnumCountMacro, + EnumString, + EnumIter, + Display, + Serialize_repr, + Deserialize_repr, )] #[repr(u8)] pub enum FieldType { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 2d70309fef..1ac65214da 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -156,6 +156,7 @@ impl GridBlockMetaPad { match cal_diff::(old, new) { None => Ok(None), Some(delta) => { + tracing::trace!("[GridBlockMeta] Composing change {}", delta.to_delta_str()); self.delta = self.delta.compose(&delta)?; Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } From 8a94644addf14855096b8d8942afb48785559ced Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 15:57:12 +0800 Subject: [PATCH 118/179] chore: config date cell ui --- .../app_flowy/lib/startup/deps_resolver.dart | 1 - .../grid/cell_bloc/checkbox_cell_bloc.dart | 46 ++++++---- .../grid/cell_bloc/date_cell_bloc.dart | 75 ++++++++++++--- .../application/grid/row/row_service.dart | 26 +++--- .../grid/src/widgets/cell/date_cell.dart | 91 ++++++++++++++++++- .../cell/selection_cell/selection_cell.dart | 7 +- .../cell/selection_cell/selection_editor.dart | 8 +- .../src/widgets/header/field_type_list.dart | 2 +- .../packages/flowy_infra/pubspec.lock | 9 +- .../packages/flowy_sdk/example/pubspec.lock | 6 +- .../windows/flutter/generated_plugins.cmake | 8 -- .../app_flowy/packages/flowy_sdk/pubspec.lock | 4 +- frontend/app_flowy/pubspec.lock | 16 +++- frontend/app_flowy/pubspec.yaml | 1 + .../field/type_options/date_type_option.rs | 5 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 2 +- .../src/entities/meta.rs | 11 ++- .../src/client_grid/grid_block_meta_pad.rs | 2 +- 18 files changed, 243 insertions(+), 77 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index a0af57f580..f54a7d0a27 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -200,7 +200,6 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (cellData, _) => DateCellBloc( - service: CellService(), cellData: cellData, ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index a2b888a295..154385f4a6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -26,15 +26,10 @@ class CheckboxCellBloc extends Bloc { _startListening(); }, select: (_Selected value) async { - _service.updateCell( - gridId: state.cellData.gridId, - fieldId: state.cellData.field.id, - rowId: state.cellData.rowId, - data: !state.isSelected ? "Yes" : "No", - ); + _updateCellData(); }, didReceiveCellUpdate: (_DidReceiveCellUpdate value) { - emit(state.copyWith(isSelected: isSelected(value.cell))); + emit(state.copyWith(isSelected: _isSelected(value.cell))); }, ); }, @@ -50,22 +45,33 @@ class CheckboxCellBloc extends Bloc { void _startListening() { _listener.updateCellNotifier.addPublishListener((result) { result.fold( - (notificationData) async { - final result = await _service.getCell( - gridId: state.cellData.gridId, - fieldId: state.cellData.field.id, - rowId: state.cellData.rowId, - ); - result.fold( - (cell) => add(CheckboxCellEvent.didReceiveCellUpdate(cell)), - (err) => Log.error(err), - ); - }, + (notificationData) async => await _loadCellData(), (err) => Log.error(err), ); }); _listener.start(); } + + Future _loadCellData() async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + result.fold( + (cell) => add(CheckboxCellEvent.didReceiveCellUpdate(cell)), + (err) => Log.error(err), + ); + } + + void _updateCellData() { + _service.updateCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + data: !state.isSelected ? "Yes" : "No", + ); + } } @freezed @@ -83,11 +89,11 @@ class CheckboxCellState with _$CheckboxCellState { }) = _CheckboxCellState; factory CheckboxCellState.initial(CellData cellData) { - return CheckboxCellState(cellData: cellData, isSelected: isSelected(cellData.cell)); + return CheckboxCellState(cellData: cellData, isSelected: _isSelected(cellData.cell)); } } -bool isSelected(Cell? cell) { +bool _isSelected(Cell? cell) { final content = cell?.content ?? ""; return content == "Yes"; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index 7a995aab28..b71ccabd3a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,5 +1,7 @@ +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -8,17 +10,28 @@ import 'cell_service.dart'; part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { - final CellService service; - final CellData cellData; + final CellService _service; + final CellListener _listener; - DateCellBloc({ - required this.service, - required this.cellData, - }) : super(DateCellState.initial()) { + DateCellBloc({required CellData cellData}) + : _service = CellService(), + _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + super(DateCellState.initial(cellData)) { on( (event, emit) async { - await event.map( - initial: (_InitialCell value) async {}, + event.map( + initial: (_InitialCell value) { + _startListening(); + }, + selectDay: (_SelectDay value) { + _updateCellData(value.day); + }, + didReceiveCellUpdate: (_DidReceiveCellUpdate value) { + emit(state.copyWith( + cellData: state.cellData.copyWith(cell: value.cell), + content: value.cell.content, + )); + }, ); }, ); @@ -26,20 +39,60 @@ class DateCellBloc extends Bloc { @override Future close() async { + await _listener.stop(); return super.close(); } + + void _startListening() { + _listener.updateCellNotifier.addPublishListener((result) { + result.fold( + (notificationData) => _loadCellData(), + (err) => Log.error(err), + ); + }); + _listener.start(); + } + + Future _loadCellData() async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + result.fold( + (cell) => add(DateCellEvent.didReceiveCellUpdate(cell)), + (err) => Log.error(err), + ); + } + + void _updateCellData(DateTime day) { + final data = day.millisecondsSinceEpoch ~/ 1000; + _service.updateCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + data: data.toString(), + ); + } } @freezed class DateCellEvent with _$DateCellEvent { const factory DateCellEvent.initial() = _InitialCell; + const factory DateCellEvent.selectDay(DateTime day) = _SelectDay; + const factory DateCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; } @freezed class DateCellState with _$DateCellState { const factory DateCellState({ - Cell? cell, + required CellData cellData, + required String content, + DateTime? selectedDay, }) = _DateCellState; - factory DateCellState.initial() => const DateCellState(); + factory DateCellState.initial(CellData cellData) => DateCellState( + cellData: cellData, + content: cellData.cell?.content ?? "", + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 8b2548b1b2..72c25e022b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -4,6 +4,9 @@ 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:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'row_service.freezed.dart'; class RowService { final String gridId; @@ -29,19 +32,12 @@ class RowService { } } -class CellData extends Equatable { - final String gridId; - final String rowId; - final Field field; - final Cell? cell; - - const CellData({ - required this.rowId, - required this.gridId, - required this.field, - required this.cell, - }); - - @override - List get props => [cell, field]; +@freezed +class CellData with _$CellData { + const factory CellData({ + required String gridId, + required String rowId, + required Field field, + Cell? cell, + }) = _CellData; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index e3b48279c0..b4692074c2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -1,7 +1,11 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:table_calendar/table_calendar.dart'; +import 'package:window_size/window_size.dart'; class DateCell extends StatefulWidget { final CellData cellData; @@ -20,7 +24,7 @@ class _DateCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellData); + _cellBloc = getIt(param1: widget.cellData)..add(const DateCellEvent.initial()); super.initState(); } @@ -30,7 +34,20 @@ class _DateCellState extends State { value: _cellBloc, child: BlocBuilder( builder: (context, state) { - return Container(); + return SizedBox.expand( + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => _CellCalendar.show( + context, + onSelected: (day) => context.read().add(DateCellEvent.selectDay(day)), + ), + child: MouseRegion( + opaque: false, + cursor: SystemMouseCursors.click, + child: FlowyText.medium(state.content, fontSize: 12), + ), + ), + ); }, ), ); @@ -42,3 +59,73 @@ class _DateCellState extends State { super.dispose(); } } + +final kToday = DateTime.now(); +final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day); +final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day); + +class _CellCalendar extends StatefulWidget { + final void Function(DateTime) onSelected; + const _CellCalendar({required this.onSelected, Key? key}) : super(key: key); + + @override + State<_CellCalendar> createState() => _CellCalendarState(); + + static Future show(BuildContext context, {required void Function(DateTime) onSelected}) async { + _CellCalendar.remove(context); + final window = await getWindowInfo(); + final calendar = _CellCalendar(onSelected: onSelected); + const size = Size(460, 400); + FlowyOverlay.of(context).insertWithRect( + widget: OverlayContainer( + child: calendar, + constraints: BoxConstraints.loose(const Size(460, 400)), + ), + identifier: _CellCalendar.identifier(), + anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), + anchorSize: window.frame.size, + anchorDirection: AnchorDirection.center, + style: FlowyOverlayStyle(blur: false), + ); + } + + static void remove(BuildContext context) { + FlowyOverlay.of(context).remove(identifier()); + } + + static String identifier() { + return (_CellCalendar).toString(); + } +} + +class _CellCalendarState extends State<_CellCalendar> { + DateTime _focusedDay = DateTime.now(); + DateTime? _selectedDay; + + @override + Widget build(BuildContext context) { + return TableCalendar( + firstDay: kFirstDay, + lastDay: kLastDay, + focusedDay: _focusedDay, + calendarFormat: CalendarFormat.month, + selectedDayPredicate: (day) { + return isSameDay(_selectedDay, day); + }, + onDaySelected: (selectedDay, focusedDay) { + if (!isSameDay(_selectedDay, selectedDay)) { + // Call `setState()` when updating the selected day + setState(() { + _selectedDay = selectedDay; + _focusedDay = focusedDay; + widget.onSelected(selectedDay); + }); + } + }, + onFormatChanged: (format) {}, + onPageChanged: (focusedDay) { + _focusedDay = focusedDay; + }, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 64e01bda53..ac0f7d391b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -86,7 +86,12 @@ class _MultiSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - SelectOptionCellEditor.show(context, state.cellData, state.options, state.selectedOptions); + SelectOptionCellEditor.show( + context, + state.cellData, + state.options, + state.selectedOptions, + ); }, child: Row(children: children), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index b6f4001c59..1685473a65 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -36,10 +36,6 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { Key? key, }) : super(key: key); - static String identifier() { - return (SelectOptionCellEditor).toString(); - } - @override Widget build(BuildContext context) { return BlocProvider( @@ -96,6 +92,10 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { FlowyOverlay.of(context).remove(identifier()); } + static String identifier() { + return (SelectOptionCellEditor).toString(); + } + @override bool asBarrier() => true; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index dfeacf4d17..2965556f60 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -19,7 +19,7 @@ class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate { @override Widget build(BuildContext context) { - final cells = FieldType.values.where((ty) => ty != FieldType.DateTime).map((fieldType) { + final cells = FieldType.values.map((fieldType) { return FieldTypeCell( fieldType: fieldType, onSelectField: (fieldType) { diff --git a/frontend/app_flowy/packages/flowy_infra/pubspec.lock b/frontend/app_flowy/packages/flowy_infra/pubspec.lock index 4cfc4b3c40..256c2dac3a 100644 --- a/frontend/app_flowy/packages/flowy_infra/pubspec.lock +++ b/frontend/app_flowy/packages/flowy_infra/pubspec.lock @@ -95,6 +95,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -176,7 +183,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" textstyle_extensions: dependency: "direct main" description: diff --git a/frontend/app_flowy/packages/flowy_sdk/example/pubspec.lock b/frontend/app_flowy/packages/flowy_sdk/example/pubspec.lock index 4ad6cc1e98..921bd4fb2b 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.8" + version: "3.1.6" async: dependency: transitive description: @@ -200,7 +200,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.0" platform: dependency: transitive description: @@ -275,7 +275,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.8" 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 33c0fd0169..d71dbaabab 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,9 +6,6 @@ list(APPEND FLUTTER_PLUGIN_LIST flowy_sdk ) -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - set(PLUGIN_BUNDLED_LIBRARIES) foreach(plugin ${FLUTTER_PLUGIN_LIST}) @@ -17,8 +14,3 @@ 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/pubspec.lock b/frontend/app_flowy/packages/flowy_sdk/pubspec.lock index b1c06d8848..1f5af870d9 100644 --- a/frontend/app_flowy/packages/flowy_sdk/pubspec.lock +++ b/frontend/app_flowy/packages/flowy_sdk/pubspec.lock @@ -346,7 +346,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.0" pedantic: dependency: transitive description: @@ -456,7 +456,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.8" timing: dependency: transitive description: diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index 24b1809e2f..428982c60e 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -512,7 +512,7 @@ packages: name: fluttertoast url: "https://pub.dartlang.org" source: hosted - version: "8.0.8" + version: "8.0.9" freezed: dependency: "direct dev" description: @@ -1031,6 +1031,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + simple_gesture_detector: + dependency: transitive + description: + name: simple_gesture_detector + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" sized_context: dependency: "direct main" description: @@ -1120,6 +1127,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.1+2" + table_calendar: + dependency: "direct main" + description: + name: table_calendar + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.5" term_glyph: dependency: transitive description: diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 4d8ec095d5..495e2482cd 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -73,6 +73,7 @@ dependencies: cupertino_icons: ^1.0.2 device_info_plus: ^3.2.1 fluttertoast: ^8.0.8 + table_calendar: ^3.0.5 dev_dependencies: flutter_lints: ^1.0.0 diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index b89431add8..bf63228287 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -69,9 +69,8 @@ impl CellDataOperation for DateTypeOption { _cell_meta: Option, ) -> Result { let changeset = changeset.into(); - if let Err(e) = changeset.parse::() { - tracing::error!("Parse {} to i64 failed: {}", changeset.to_string(), e); - return Err(FlowyError::internal().context(e)); + if changeset.parse::().is_err() || changeset.parse::().is_err() { + return Err(FlowyError::internal().context(format!("Parse {} failed", changeset.to_string()))); }; Ok(TypeOptionCellData::new(changeset, self.field_type()).json()) diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 6ae356346c..6c0be5c1c5 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -74,7 +74,7 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("lib_ot={}", level)); filters.push(format!("lib_ws={}", level)); filters.push(format!("lib_infra={}", level)); - filters.push(format!("flowy_sync={}", level)); + filters.push(format!("flowy_sync={}", "debug")); filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_database={}", "info")); diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 2178a49f24..a7354d3668 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -8,7 +8,6 @@ use std::collections::HashMap; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 42; -pub const DEFAULT_FIELD_WIDTH: i32 = 150; #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct GridMeta { @@ -110,6 +109,7 @@ pub struct FieldMeta { impl FieldMeta { pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { + let width = field_type.default_cell_width(); Self { id: uuid::Uuid::new_v4().to_string(), name: name.to_string(), @@ -117,7 +117,7 @@ impl FieldMeta { field_type, frozen: false, visibility: true, - width: DEFAULT_FIELD_WIDTH, + width, type_options: Default::default(), } } @@ -270,6 +270,13 @@ impl FieldType { let ty = self.clone(); format!("{}", ty as u8) } + + pub fn default_cell_width(&self) -> i32 { + match self { + FieldType::DateTime => 180, + _ => 150, + } + } } #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 1ac65214da..11cb625762 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -156,7 +156,7 @@ impl GridBlockMetaPad { match cal_diff::(old, new) { None => Ok(None), Some(delta) => { - tracing::trace!("[GridBlockMeta] Composing change {}", delta.to_delta_str()); + tracing::debug!("[GridBlockMeta] Composing change {}", delta.to_delta_str()); self.delta = self.delta.compose(&delta)?; Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } From a53ffdfade5cb3d14718f47de0ed798f06399313 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 16:15:26 +0800 Subject: [PATCH 119/179] chore: update cell when field changed --- .../grid/cell_bloc/date_cell_bloc.dart | 22 ++++++++++++++----- .../grid/cell_bloc/selection_cell_bloc.dart | 22 ++++++++++++++----- .../grid/src/widgets/cell/date_cell.dart | 12 +++++++--- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index b71ccabd3a..10887860dd 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; @@ -11,11 +12,13 @@ part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { final CellService _service; - final CellListener _listener; + final CellListener _cellListener; + final FieldListener _fieldListener; DateCellBloc({required CellData cellData}) : _service = CellService(), - _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _fieldListener = FieldListener(fieldId: cellData.field.id), super(DateCellState.initial(cellData)) { on( (event, emit) async { @@ -39,18 +42,27 @@ class DateCellBloc extends Bloc { @override Future close() async { - await _listener.stop(); + await _cellListener.stop(); + await _fieldListener.stop(); return super.close(); } void _startListening() { - _listener.updateCellNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier.addPublishListener((result) { result.fold( (notificationData) => _loadCellData(), (err) => Log.error(err), ); }); - _listener.start(); + _cellListener.start(); + + _fieldListener.updateFieldNotifier.addPublishListener((result) { + result.fold( + (field) => _loadCellData(), + (err) => Log.error(err), + ); + }); + _fieldListener.start(); } Future _loadCellData() async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index b12b56b827..d472016bfc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/select_option_service.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; @@ -11,12 +12,14 @@ part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { final SelectOptionService _service; - final CellListener _listener; + final CellListener _cellListener; + final FieldListener _fieldListener; SelectionCellBloc({ required CellData cellData, }) : _service = SelectOptionService(), - _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _fieldListener = FieldListener(fieldId: cellData.field.id), super(SelectionCellState.initial(cellData)) { on( (event, emit) async { @@ -35,7 +38,8 @@ class SelectionCellBloc extends Bloc { @override Future close() async { - await _listener.stop(); + await _cellListener.stop(); + await _fieldListener.stop(); return super.close(); } @@ -56,13 +60,21 @@ class SelectionCellBloc extends Bloc { } void _startListening() { - _listener.updateCellNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier.addPublishListener((result) { result.fold( (notificationData) => _loadOptions(), (err) => Log.error(err), ); }); - _listener.start(); + _cellListener.start(); + + _fieldListener.updateFieldNotifier.addPublishListener((result) { + result.fold( + (field) => _loadOptions(), + (err) => Log.error(err), + ); + }); + _fieldListener.start(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index b4692074c2..70febd9adf 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -44,7 +44,7 @@ class _DateCellState extends State { child: MouseRegion( opaque: false, cursor: SystemMouseCursors.click, - child: FlowyText.medium(state.content, fontSize: 12), + child: Center(child: FlowyText.medium(state.content, fontSize: 12)), ), ), ); @@ -99,6 +99,7 @@ class _CellCalendar extends StatefulWidget { } class _CellCalendarState extends State<_CellCalendar> { + CalendarFormat _calendarFormat = CalendarFormat.month; DateTime _focusedDay = DateTime.now(); DateTime? _selectedDay; @@ -108,7 +109,8 @@ class _CellCalendarState extends State<_CellCalendar> { firstDay: kFirstDay, lastDay: kLastDay, focusedDay: _focusedDay, - calendarFormat: CalendarFormat.month, + calendarFormat: _calendarFormat, + headerStyle: const HeaderStyle(formatButtonVisible: false), selectedDayPredicate: (day) { return isSameDay(_selectedDay, day); }, @@ -122,7 +124,11 @@ class _CellCalendarState extends State<_CellCalendar> { }); } }, - onFormatChanged: (format) {}, + onFormatChanged: (format) { + setState(() { + _calendarFormat = format; + }); + }, onPageChanged: (focusedDay) { _focusedDay = focusedDay; }, From ed10ebac7a89e019406499c1c98bbb30acabe104 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 20:45:33 +0800 Subject: [PATCH 120/179] fix: add new select option tag from textfield --- .../grid/cell_bloc/selection_editor_bloc.dart | 14 ++- .../workspace/application/grid/grid_bloc.dart | 45 +------- .../application/grid/row/row_service.dart | 32 +++++- .../plugins/grid/src/grid_page.dart | 1 + .../cell/selection_cell/extension.dart | 96 ----------------- .../cell/selection_cell/selection_editor.dart | 5 +- .../cell/selection_cell/text_field.dart | 101 ++++++++++++++++++ .../type_options/selection_type_option.rs | 61 +++++------ 8 files changed, 174 insertions(+), 181 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index d2606b0fdb..5b6ba78bd5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -110,7 +110,7 @@ class SelectOptionEditorBloc extends Bloc add(SelectOptionEditorEvent.didReceiveOptions( - selectOptionContext.options, - selectOptionContext.selectOptions, - )), + (selectOptionContext) { + if (!isClosed) { + add(SelectOptionEditorEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )); + } + }, (err) => Log.error(err), ); }, 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 01db1f1300..33d3cbe40c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; @@ -6,7 +7,6 @@ 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 'package:equatable/equatable.dart'; import 'grid_block_service.dart'; import 'field/grid_listenr.dart'; import 'grid_service.dart'; @@ -154,46 +154,3 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.loading() = _Loading; const factory GridLoadingState.finish(Either successOrFail) = _Finish; } - -class GridBlockRow { - final String gridId; - final String rowId; - final String blockId; - final double height; - - const GridBlockRow({ - required this.gridId, - required this.rowId, - required this.blockId, - required this.height, - }); -} - -class RowData extends Equatable { - final String gridId; - final String rowId; - final String blockId; - final List fields; - final double height; - - const RowData({ - required this.gridId, - required this.rowId, - required this.blockId, - required this.fields, - required this.height, - }); - - factory RowData.fromBlockRow(GridBlockRow row, List fields) { - return RowData( - gridId: row.gridId, - rowId: row.rowId, - blockId: row.blockId, - fields: fields, - height: row.height, - ); - } - - @override - List get props => [rowId, fields]; -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 72c25e022b..7ed5477364 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,5 +1,4 @@ import 'package:dartz/dartz.dart'; -import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; @@ -41,3 +40,34 @@ class CellData with _$CellData { Cell? cell, }) = _CellData; } + +@freezed +class RowData with _$RowData { + const factory RowData({ + required String gridId, + required String rowId, + required String blockId, + required List fields, + required double height, + }) = _RowData; + + factory RowData.fromBlockRow(GridBlockRow row, List fields) { + return RowData( + gridId: row.gridId, + rowId: row.rowId, + blockId: row.blockId, + fields: fields, + height: row.height, + ); + } +} + +@freezed +class GridBlockRow with _$GridBlockRow { + const factory GridBlockRow({ + required String gridId, + required String rowId, + required String blockId, + required double height, + }) = _GridBlockRow; +} 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 936ad68c44..5de9cc75a6 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.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'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index d94e11dde0..bdf4d01158 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -1,6 +1,3 @@ -import 'dart:collection'; - -import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; @@ -8,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:textfield_tags/textfield_tags.dart'; extension SelectOptionColorExtension on SelectOptionColor { Color make(BuildContext context) { @@ -63,98 +59,6 @@ extension SelectOptionColorExtension on SelectOptionColor { } } -class SelectOptionTextField extends StatelessWidget { - final FocusNode _focusNode; - final TextEditingController _controller; - final TextfieldTagsController tagController; - final List options; - final LinkedHashMap selectedOptionMap; - - final double distanceToText; - - final Function(String) onNewTag; - - SelectOptionTextField({ - required this.options, - required this.selectedOptionMap, - required this.distanceToText, - required this.tagController, - required this.onNewTag, - TextEditingController? controller, - FocusNode? focusNode, - Key? key, - }) : _controller = controller ?? TextEditingController(), - _focusNode = focusNode ?? FocusNode(), - super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - - return TextFieldTags( - textEditingController: _controller, - textfieldTagsController: tagController, - initialTags: selectedOptionMap.keys.toList(), - focusNode: _focusNode, - textSeparators: const [' ', ','], - inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) { - return ((context, sc, tags, onTagDelegate) { - tags.retainWhere((name) { - return options.where((option) => option.name == name).isEmpty; - }); - if (tags.isNotEmpty) { - assert(tags.length == 1); - onNewTag(tags.first); - } - - return TextField( - autofocus: true, - controller: editController, - focusNode: focusNode, - onChanged: onChanged, - onSubmitted: onSubmitted, - maxLines: 1, - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: theme.main1, width: 1.0), - borderRadius: Corners.s10Border, - ), - isDense: true, - prefixIcon: _renderTags(sc), - hintText: LocaleKeys.grid_selectOption_searchOption.tr(), - prefixIconConstraints: BoxConstraints(maxWidth: distanceToText), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: theme.main1, - width: 1.0, - ), - borderRadius: Corners.s10Border, - ), - ), - ); - }); - }, - ); - } - - Widget? _renderTags(ScrollController sc) { - if (selectedOptionMap.isEmpty) { - return null; - } - - final children = selectedOptionMap.values.map((option) => SelectOptionTag(option: option)).toList(); - return Padding( - padding: const EdgeInsets.all(8.0), - child: SingleChildScrollView( - controller: sc, - scrollDirection: Axis.horizontal, - child: Row(children: children), - ), - ); - } -} - class SelectOptionTag extends StatelessWidget { final SelectOption option; final bool isSelected; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 1685473a65..ebaabbfb0b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -1,5 +1,4 @@ import 'dart:collection'; - import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; @@ -21,6 +20,7 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:textfield_tags/textfield_tags.dart'; import 'extension.dart'; +import 'text_field.dart'; const double _editorPannelWidth = 300; @@ -135,8 +135,7 @@ class _TextField extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocConsumer( - listener: (context, state) {}, + return BlocBuilder( builder: (context, state) { final optionMap = LinkedHashMap.fromIterable(state.selectedOptions, key: (option) => option.name, value: (option) => option); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart new file mode 100644 index 0000000000..e7f4e98851 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart @@ -0,0 +1,101 @@ +import 'dart:collection'; + +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:textfield_tags/textfield_tags.dart'; + +import 'extension.dart'; + +class SelectOptionTextField extends StatelessWidget { + final FocusNode _focusNode; + final TextEditingController _controller; + final TextfieldTagsController tagController; + final List options; + final LinkedHashMap selectedOptionMap; + + final double distanceToText; + + final Function(String) onNewTag; + + SelectOptionTextField({ + required this.options, + required this.selectedOptionMap, + required this.distanceToText, + required this.tagController, + required this.onNewTag, + TextEditingController? controller, + FocusNode? focusNode, + Key? key, + }) : _controller = controller ?? TextEditingController(), + _focusNode = focusNode ?? FocusNode(), + super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return TextFieldTags( + textEditingController: _controller, + textfieldTagsController: tagController, + initialTags: selectedOptionMap.keys.toList(), + focusNode: _focusNode, + textSeparators: const [' ', ','], + inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) { + return ((context, sc, tags, onTagDelegate) { + return TextField( + autofocus: true, + controller: editController, + focusNode: focusNode, + onChanged: onChanged, + onSubmitted: (text) { + if (onSubmitted != null) { + onSubmitted(text); + } + + if (text.isNotEmpty) { + onNewTag(text); + } + }, + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: theme.main1, width: 1.0), + borderRadius: Corners.s10Border, + ), + isDense: true, + prefixIcon: _renderTags(sc), + hintText: LocaleKeys.grid_selectOption_searchOption.tr(), + prefixIconConstraints: BoxConstraints(maxWidth: distanceToText), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: theme.main1, width: 1.0), + borderRadius: Corners.s10Border, + ), + ), + ); + }); + }, + ); + } + + Widget? _renderTags(ScrollController sc) { + if (selectedOptionMap.isEmpty) { + return null; + } + + final children = selectedOptionMap.values.map((option) => SelectOptionTag(option: option)).toList(); + return Padding( + padding: const EdgeInsets.all(8.0), + child: SingleChildScrollView( + controller: sc, + scrollDirection: Axis.horizontal, + child: Row(children: children), + ), + ); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index bcf21972ce..30cd36b122 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -16,9 +16,28 @@ use std::str::FromStr; pub const SELECTION_IDS_SEPARATOR: &str = ","; pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync { - fn insert_option(&mut self, new_option: SelectOption); - fn delete_option(&mut self, delete_option: SelectOption); + fn insert_option(&mut self, new_option: SelectOption) { + let options = self.mut_options(); + if let Some(index) = options + .iter() + .position(|option| option.id == new_option.id || option.name == new_option.name) + { + options.remove(index); + options.insert(index, new_option); + } else { + options.insert(0, new_option); + } + } + + fn delete_option(&mut self, delete_option: SelectOption) { + let options = self.mut_options(); + if let Some(index) = options.iter().position(|option| option.id == delete_option.id) { + options.remove(index); + } + } + fn option_context(&self, cell_meta: &Option) -> SelectOptionContext; + fn mut_options(&mut self) -> &mut Vec; } // Single select @@ -33,21 +52,6 @@ pub struct SingleSelectTypeOption { impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); impl SelectOptionOperation for SingleSelectTypeOption { - fn insert_option(&mut self, new_option: SelectOption) { - if let Some(index) = self.options.iter().position(|option| option.id == new_option.id) { - self.options.remove(index); - self.options.insert(index, new_option); - } else { - self.options.insert(0, new_option); - } - } - - fn delete_option(&mut self, delete_option: SelectOption) { - if let Some(index) = self.options.iter().position(|option| option.id == delete_option.id) { - self.options.remove(index); - } - } - fn option_context(&self, cell_meta: &Option) -> SelectOptionContext { let select_options = make_select_context_from(cell_meta, &self.options); SelectOptionContext { @@ -55,6 +59,10 @@ impl SelectOptionOperation for SingleSelectTypeOption { select_options, } } + + fn mut_options(&mut self) -> &mut Vec { + &mut self.options + } } impl CellDataOperation for SingleSelectTypeOption { @@ -139,21 +147,6 @@ impl MultiSelectTypeOption { } impl SelectOptionOperation for MultiSelectTypeOption { - fn insert_option(&mut self, new_option: SelectOption) { - if let Some(index) = self.options.iter().position(|option| option.id == new_option.id) { - self.options.remove(index); - self.options.insert(index, new_option); - } else { - self.options.insert(0, new_option); - } - } - - fn delete_option(&mut self, delete_option: SelectOption) { - if let Some(index) = self.options.iter().position(|option| option.id == delete_option.id) { - self.options.remove(index); - } - } - fn option_context(&self, cell_meta: &Option) -> SelectOptionContext { let select_options = make_select_context_from(cell_meta, &self.options); SelectOptionContext { @@ -161,6 +154,10 @@ impl SelectOptionOperation for MultiSelectTypeOption { select_options, } } + + fn mut_options(&mut self) -> &mut Vec { + &mut self.options + } } impl CellDataOperation for MultiSelectTypeOption { From b93feb49c32aebdcee2902b2679bb7a604262422 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 22:07:48 +0800 Subject: [PATCH 121/179] chore: config row action sheet --- .../app_flowy/assets/translations/en.json | 4 + .../app_flowy/lib/startup/deps_resolver.dart | 1 - ...bloc.dart => field_action_sheet_bloc.dart} | 28 ++-- .../workspace/application/grid/grid_bloc.dart | 1 - .../workspace/application/grid/prelude.dart | 2 +- .../grid/row/row_action_sheet_bloc.dart | 58 ++++++++ .../application/grid/row/row_bloc.dart | 52 +++---- .../application/grid/row/row_service.dart | 22 ++- .../plugins/grid/src/grid_page.dart | 30 ++-- .../plugins/grid/src/layout/sizes.dart | 2 +- .../header/field_cell_action_sheet.dart | 20 +-- .../grid/src/widgets/row/grid_row.dart | 36 ++++- .../src/widgets/row/row_action_sheet.dart | 133 ++++++++++++++++++ .../dart_event/flowy-grid/dart_event.dart | 34 +++++ .../protobuf/flowy-grid/event_map.pbenum.dart | 4 + .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 16 +++ frontend/rust-lib/flowy-grid/src/event_map.rs | 8 ++ .../src/protobuf/model/event_map.rs | 13 +- .../src/protobuf/proto/event_map.proto | 2 + 20 files changed, 379 insertions(+), 91 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/field/{action_sheet_bloc.dart => field_action_sheet_bloc.dart} (67%) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 7e20a947dc..83a7826918 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -174,6 +174,10 @@ "addOption": "Add option", "editProperty": "Edit property" }, + "row": { + "duplicate": "Duplicate", + "delete": "Delete" + }, "selectOption": { "purpleColor": "Purple", "pinkColor": "Pink", diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index f54a7d0a27..5f69ab1ad4 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -154,7 +154,6 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (data, _) => RowBloc( rowData: data, - rowlistener: RowListener(rowId: data.rowId), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/action_sheet_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_action_sheet_bloc.dart similarity index 67% rename from frontend/app_flowy/lib/workspace/application/grid/field/action_sheet_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/field_action_sheet_bloc.dart index 5e8cb5a932..40ac699e7f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/action_sheet_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_action_sheet_bloc.dart @@ -5,14 +5,14 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'field_service.dart'; -part 'action_sheet_bloc.freezed.dart'; +part 'field_action_sheet_bloc.freezed.dart'; -class FieldActionSheetBloc extends Bloc { +class FieldActionSheetBloc extends Bloc { final FieldService service; FieldActionSheetBloc({required Field field, required this.service}) - : super(ActionSheetState.initial(EditFieldContext.create()..gridField = field)) { - on( + : super(FieldActionSheetState.initial(EditFieldContext.create()..gridField = field)) { + on( (event, emit) async { await event.map( updateFieldName: (_UpdateFieldName value) async { @@ -56,23 +56,23 @@ class FieldActionSheetBloc extends Bloc { } @freezed -class ActionSheetEvent with _$ActionSheetEvent { - const factory ActionSheetEvent.updateFieldName(String name) = _UpdateFieldName; - const factory ActionSheetEvent.hideField() = _HideField; - const factory ActionSheetEvent.duplicateField() = _DuplicateField; - const factory ActionSheetEvent.deleteField() = _DeleteField; - const factory ActionSheetEvent.saveField() = _SaveField; +class FieldActionSheetEvent with _$FieldActionSheetEvent { + const factory FieldActionSheetEvent.updateFieldName(String name) = _UpdateFieldName; + const factory FieldActionSheetEvent.hideField() = _HideField; + const factory FieldActionSheetEvent.duplicateField() = _DuplicateField; + const factory FieldActionSheetEvent.deleteField() = _DeleteField; + const factory FieldActionSheetEvent.saveField() = _SaveField; } @freezed -class ActionSheetState with _$ActionSheetState { - const factory ActionSheetState({ +class FieldActionSheetState with _$FieldActionSheetState { + const factory FieldActionSheetState({ required EditFieldContext editContext, required String errorText, required String fieldName, - }) = _ActionSheetState; + }) = _FieldActionSheetState; - factory ActionSheetState.initial(EditFieldContext editContext) => ActionSheetState( + factory FieldActionSheetState.initial(EditFieldContext editContext) => FieldActionSheetState( editContext: editContext, errorText: '', fieldName: editContext.gridField.name, 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 33d3cbe40c..a46136a6b5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -111,7 +111,6 @@ class GridBloc extends Bloc { rows.addAll(gridBlock.rowOrders.map( (rowOrder) => GridBlockRow( gridId: view.id, - blockId: gridBlock.id, rowId: rowOrder.rowId, height: rowOrder.height.toDouble(), ), diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index f941b01056..a795e23fb2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -7,7 +7,7 @@ export 'data.dart'; // Field export 'field/field_service.dart'; export 'field/grid_header_bloc.dart'; -export 'field/action_sheet_bloc.dart'; +export 'field/field_action_sheet_bloc.dart'; export 'field/field_editor_bloc.dart'; export 'field/field_switch_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart new file mode 100644 index 0000000000..93ee70afa0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart @@ -0,0 +1,58 @@ +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'package:dartz/dartz.dart'; + +part 'row_action_sheet_bloc.freezed.dart'; + +class RowActionSheetBloc extends Bloc { + final RowService _rowService; + + RowActionSheetBloc({required RowData rowData}) + : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), + super(RowActionSheetState.initial(rowData)) { + on( + (event, emit) async { + await event.map( + deleteRow: (_DeleteRow value) async { + final result = await _rowService.deleteRow(); + logResult(result); + }, + duplicateRow: (_DuplicateRow value) async { + final result = await _rowService.duplicateRow(); + logResult(result); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } + + void logResult(Either result) { + result.fold((l) => null, (err) => Log.error(err)); + } +} + +@freezed +class RowActionSheetEvent with _$RowActionSheetEvent { + const factory RowActionSheetEvent.duplicateRow() = _DuplicateRow; + const factory RowActionSheetEvent.deleteRow() = _DeleteRow; +} + +@freezed +class RowActionSheetState with _$RowActionSheetState { + const factory RowActionSheetState({ + required RowData rowData, + }) = _RowActionSheetState; + + factory RowActionSheetState.initial(RowData rowData) => RowActionSheetState( + rowData: rowData, + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 418cb23e88..6c0037d289 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,7 +1,6 @@ import 'dart:collection'; import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; -import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -16,19 +15,14 @@ part 'row_bloc.freezed.dart'; typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { - final RowService rowService; - final RowListener rowlistener; - final GridFieldsListener fieldListener; + final RowService _rowService; + final RowListener _rowlistener; + final GridFieldsListener _fieldListener; - RowBloc({required RowData rowData, required this.rowlistener}) - : rowService = RowService( - gridId: rowData.gridId, - blockId: rowData.blockId, - rowId: rowData.rowId, - ), - fieldListener = GridFieldsListener( - gridId: rowData.gridId, - ), + RowBloc({required RowData rowData}) + : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), + _fieldListener = GridFieldsListener(gridId: rowData.gridId), + _rowlistener = RowListener(rowId: rowData.rowId), super(RowState.initial(rowData)) { on( (event, emit) async { @@ -38,7 +32,7 @@ class RowBloc extends Bloc { await _loadRow(emit); }, createRow: (_CreateRow value) { - rowService.createRow(); + _rowService.createRow(); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) async { await _handleFieldUpdate(emit, value); @@ -52,7 +46,7 @@ class RowBloc extends Bloc { } void _handleRowUpdate(_DidUpdateRow value, Emitter emit) { - final CellDataMap cellDataMap = _makeCellDatas(value.row, state.fields); + final CellDataMap cellDataMap = _makeCellDatas(value.row, state.rowData.fields); emit(state.copyWith( row: Future(() => Some(value.row)), cellDataMap: Some(cellDataMap), @@ -67,39 +61,39 @@ class RowBloc extends Bloc { ); emit(state.copyWith( - fields: value.fields, + rowData: state.rowData.copyWith(fields: value.fields), cellDataMap: Some(cellDataMap), )); } @override Future close() async { - await rowlistener.stop(); - await fieldListener.stop(); + await _rowlistener.stop(); + await _fieldListener.stop(); return super.close(); } Future _startListening() async { - rowlistener.updateRowNotifier.addPublishListener((result) { + _rowlistener.updateRowNotifier.addPublishListener((result) { result.fold( (row) => add(RowEvent.didUpdateRow(row)), (err) => Log.error(err), ); }); - fieldListener.updateFieldsNotifier.addPublishListener((result) { + _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( (fields) => add(RowEvent.didReceiveFieldUpdate(fields)), (err) => Log.error(err), ); }); - rowlistener.start(); - fieldListener.start(); + _rowlistener.start(); + _fieldListener.start(); } Future _loadRow(Emitter emit) async { - rowService.getRow().then((result) { + _rowService.getRow().then((result) { return result.fold( (row) => add(RowEvent.didUpdateRow(row)), (err) => Log.error(err), @@ -113,7 +107,7 @@ class RowBloc extends Bloc { if (field.visibility) { map[field.id] = CellData( rowId: row.id, - gridId: rowService.gridId, + gridId: _rowService.gridId, cell: row.cellByFieldId[field.id], field: field, ); @@ -134,17 +128,13 @@ class RowEvent with _$RowEvent { @freezed class RowState with _$RowState { const factory RowState({ - required String rowId, - required double rowHeight, - required List fields, + required RowData rowData, required Future> row, required Option cellDataMap, }) = _RowState; - factory RowState.initial(RowData data) => RowState( - rowId: data.rowId, - rowHeight: data.height, - fields: data.fields, + factory RowState.initial(RowData rowData) => RowState( + rowData: rowData, row: Future(() => none()), cellDataMap: none(), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 7ed5477364..f87d9f8574 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -10,9 +10,8 @@ part 'row_service.freezed.dart'; class RowService { final String gridId; final String rowId; - final String blockId; - RowService({required this.gridId, required this.rowId, required this.blockId}); + RowService({required this.gridId, required this.rowId}); Future> createRow() { CreateRowPayload payload = CreateRowPayload.create() @@ -29,6 +28,22 @@ class RowService { return GridEventGetRow(payload).send(); } + + Future> deleteRow() { + final payload = RowIdentifierPayload.create() + ..gridId = gridId + ..rowId = rowId; + + return GridEventDeleteRow(payload).send(); + } + + Future> duplicateRow() { + final payload = RowIdentifierPayload.create() + ..gridId = gridId + ..rowId = rowId; + + return GridEventDuplicateRow(payload).send(); + } } @freezed @@ -46,7 +61,6 @@ class RowData with _$RowData { const factory RowData({ required String gridId, required String rowId, - required String blockId, required List fields, required double height, }) = _RowData; @@ -55,7 +69,6 @@ class RowData with _$RowData { return RowData( gridId: row.gridId, rowId: row.rowId, - blockId: row.blockId, fields: fields, height: row.height, ); @@ -67,7 +80,6 @@ class GridBlockRow with _$GridBlockRow { const factory GridBlockRow({ required String gridId, required String rowId, - required String blockId, required double height, }) = _GridBlockRow; } 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 5de9cc75a6..b96b89ba2e 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 @@ -73,6 +73,7 @@ class FlowyGrid extends StatefulWidget { class _FlowyGridState extends State { final _scrollController = GridScrollController(); + final _key = GlobalKey(); @override void dispose() { @@ -91,6 +92,7 @@ class _FlowyGridState extends State { return const Center(child: CircularProgressIndicator.adaptive()); } +// _key.currentState.insertItem(index) final child = BlocBuilder( builder: (context, state) { return SizedBox( @@ -153,20 +155,24 @@ class _FlowyGridState extends State { return rowChanged; }, builder: (context, state) { - return SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) { - final blockRow = context.read().state.rows[index]; - final fields = context.read().state.fields; - final rowData = RowData.fromBlockRow(blockRow, fields); - return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)); - }, - childCount: context.read().state.rows.length, - addRepaintBoundaries: true, - addAutomaticKeepAlives: true, - ), + return SliverAnimatedList( + key: _key, + initialItemCount: context.read().state.rows.length, + itemBuilder: (BuildContext context, int index, Animation animation) { + final blockRow = context.read().state.rows[index]; + final fields = context.read().state.fields; + final rowData = RowData.fromBlockRow(blockRow, fields); + return _renderRow(rowData, animation); + }, ); }, ); } + + Widget _renderRow(RowData rowData, Animation animation) { + return SizeTransition( + sizeFactor: animation, + child: GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)), + ); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 23a541e610..8dc0b20263 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -6,7 +6,7 @@ class GridSize { static double get scrollBarSize => 12 * scale; static double get headerHeight => 40 * scale; static double get footerHeight => 40 * scale; - static double get leadingHeaderPadding => 30 * scale; + static double get leadingHeaderPadding => 50 * scale; static double get trailHeaderPadding => 140 * scale; static double get headerContainerPadding => 0 * scale; static double get cellHPadding => 10 * scale; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart index 42d49b69fe..2dc1e2976b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart @@ -23,7 +23,7 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate child: this, constraints: BoxConstraints.loose(const Size(240, 200)), ), - identifier: identifier(), + identifier: GridFieldCellActionSheet.identifier(), anchorContext: overlayContext, anchorDirection: AnchorDirection.bottomWithLeftAligned, delegate: this, @@ -68,7 +68,7 @@ class _EditFieldButton extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); - return BlocBuilder( + return BlocBuilder( builder: (context, state) { return SizedBox( height: GridSize.typeOptionItemHeight, @@ -100,16 +100,6 @@ class _FieldOperationList extends StatelessWidget { ) .toList(); - return FieldOperationList(actions: actions); - } -} - -class FieldOperationList extends StatelessWidget { - final List actions; - const FieldOperationList({required this.actions, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { return GridView( // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html shrinkWrap: true, @@ -182,13 +172,13 @@ extension _FieldActionExtension on FieldAction { void run(BuildContext context) { switch (this) { case FieldAction.hide: - context.read().add(const ActionSheetEvent.hideField()); + context.read().add(const FieldActionSheetEvent.hideField()); break; case FieldAction.duplicate: - context.read().add(const ActionSheetEvent.duplicateField()); + context.read().add(const FieldActionSheetEvent.duplicateField()); break; case FieldAction.delete: - context.read().add(const ActionSheetEvent.deleteField()); + context.read().add(const FieldActionSheetEvent.deleteField()); break; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 08d68f197a..a5b6a405a6 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -5,10 +5,13 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/p import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; +import 'row_action_sheet.dart'; + class GridRowWidget extends StatefulWidget { final RowData data; const GridRowWidget({required this.data, Key? key}) : super(key: key); @@ -39,10 +42,10 @@ class _GridRowWidgetState extends State { onEnter: (p) => _rowStateNotifier.onEnter = true, onExit: (p) => _rowStateNotifier.onEnter = false, child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, + buildWhen: (p, c) => p.rowData.height != c.rowData.height, builder: (context, state) { return SizedBox( - height: _rowBloc.state.rowHeight, + height: _rowBloc.state.rowData.height, child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: const [ @@ -83,7 +86,8 @@ class _RowLeading extends StatelessWidget { return Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ - AppendRowButton(), + _InsertRowButton(), + _DeleteRowButton(), ], ); } @@ -98,15 +102,16 @@ class _RowTrailing extends StatelessWidget { } } -class AppendRowButton extends StatelessWidget { - const AppendRowButton({Key? key}) : super(key: key); +class _InsertRowButton extends StatelessWidget { + const _InsertRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final theme = context.watch(); return FlowyIconButton( hoverColor: theme.hover, - width: 22, + width: 20, + height: 30, onPressed: () => context.read().add(const RowEvent.createRow()), iconPadding: const EdgeInsets.all(3), icon: svgWidget("home/add"), @@ -114,6 +119,25 @@ class AppendRowButton extends StatelessWidget { } } +class _DeleteRowButton extends StatelessWidget { + const _DeleteRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyIconButton( + hoverColor: theme.hover, + width: 20, + height: 30, + onPressed: () => GridRowActionSheet( + rowData: context.read().state.rowData, + ).show(context), + iconPadding: const EdgeInsets.all(3), + icon: svgWidget("editor/details"), + ); + } +} + class _RowCells extends StatelessWidget { const _RowCells({Key? key}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart new file mode 100644 index 0000000000..f1ff46af08 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart @@ -0,0 +1,133 @@ +import 'package:app_flowy/workspace/application/grid/row/row_action_sheet_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class GridRowActionSheet extends StatelessWidget { + final RowData rowData; + const GridRowActionSheet({required this.rowData, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => RowActionSheetBloc(rowData: rowData), + child: BlocBuilder( + builder: (context, state) { + final cells = _RowAction.values + .map( + (action) => _RowActionCell( + action: action, + onDismissed: () => remove(context), + ), + ) + .toList(); + + // + final list = ListView.separated( + shrinkWrap: true, + controller: ScrollController(), + itemCount: cells.length, + separatorBuilder: (context, index) { + return VSpace(GridSize.typeOptionSeparatorHeight); + }, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + ); + return list; + }, + ), + ); + } + + void show(BuildContext overlayContext) { + FlowyOverlay.of(overlayContext).insertWithAnchor( + widget: OverlayContainer( + child: this, + constraints: BoxConstraints.loose(const Size(140, 200)), + ), + identifier: GridRowActionSheet.identifier(), + anchorContext: overlayContext, + anchorDirection: AnchorDirection.leftWithCenterAligned, + ); + } + + void remove(BuildContext overlayContext) { + FlowyOverlay.of(overlayContext).remove(GridRowActionSheet.identifier()); + } + + static String identifier() { + return (GridRowActionSheet).toString(); + } +} + +class _RowActionCell extends StatelessWidget { + final _RowAction action; + final VoidCallback onDismissed; + const _RowActionCell({required this.action, required this.onDismissed, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(action.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + action.performAction(context); + onDismissed(); + }, + leftIcon: svgWidget(action.iconName(), color: theme.iconColor), + ), + ); + } +} + +enum _RowAction { + delete, + duplicate, +} + +extension _RowActionExtension on _RowAction { + String iconName() { + switch (this) { + case _RowAction.duplicate: + return 'grid/duplicate'; + case _RowAction.delete: + return 'grid/delete'; + } + } + + String title() { + switch (this) { + case _RowAction.duplicate: + return LocaleKeys.grid_row_duplicate.tr(); + case _RowAction.delete: + return LocaleKeys.grid_row_delete.tr(); + } + } + + void performAction(BuildContext context) { + switch (this) { + case _RowAction.duplicate: + // context.read().add(const RowActionSheetEvent.duplicateRow()); + break; + case _RowAction.delete: + // context.read().add(const RowActionSheetEvent.deleteRow()); + break; + } + } +} 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 a4871a6bef..8544bc6edd 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 @@ -239,6 +239,40 @@ class GridEventGetRow { } } +class GridEventDeleteRow { + RowIdentifierPayload request; + GridEventDeleteRow(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.DeleteRow.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class GridEventDuplicateRow { + RowIdentifierPayload request; + GridEventDuplicateRow(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.DuplicateRow.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventGetCell { CellIdentifierPayload request; GridEventGetCell(this.request); 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 37032ec41b..5be5844119 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 @@ -24,6 +24,8 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent ApplySelectOptionChangeset = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); + static const GridEvent DeleteRow = GridEvent._(52, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteRow'); + static const GridEvent DuplicateRow = GridEvent._(53, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateRow'); static const GridEvent GetCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCell'); static const GridEvent UpdateCell = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); @@ -43,6 +45,8 @@ class GridEvent extends $pb.ProtobufEnum { ApplySelectOptionChangeset, CreateRow, GetRow, + DeleteRow, + DuplicateRow, GetCell, UpdateCell, ApplySelectOptionCellChangeset, 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 bc4b838bca..2f2921564b 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 @@ -26,6 +26,8 @@ const GridEvent$json = const { const {'1': 'ApplySelectOptionChangeset', '2': 32}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, + const {'1': 'DeleteRow', '2': 52}, + const {'1': 'DuplicateRow', '2': 53}, const {'1': 'GetCell', '2': 70}, const {'1': 'UpdateCell', '2': 71}, const {'1': 'ApplySelectOptionCellChangeset', '2': 72}, @@ -33,4 +35,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSIgoeQXBwbHlTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0EEg='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg0KCURlbGV0ZVJvdxA0EhAKDER1cGxpY2F0ZVJvdxA1EgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSIgoeQXBwbHlTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0EEg='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 467c3e334b..d94753c4b0 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -179,6 +179,22 @@ pub(crate) async fn get_row_handler( } } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn delete_row_handler( + data: Data, + manager: AppData>, +) -> DataResult { + todo!() +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn duplicate_row_handler( + data: Data, + manager: AppData>, +) -> DataResult { + todo!() +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_row_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 8a4c68e468..7246cc7f4f 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -20,6 +20,8 @@ pub fn create(grid_manager: Arc) -> Module { // Row .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) + .event(GridEvent::DeleteRow, delete_row_handler) + .event(GridEvent::DuplicateRow, duplicate_row_handler) // Cell .event(GridEvent::GetCell, get_cell_handler) .event(GridEvent::UpdateCell, update_cell_handler) @@ -81,6 +83,12 @@ pub enum GridEvent { #[event(input = "RowIdentifierPayload", output = "Row")] GetRow = 51, + #[event(input = "RowIdentifierPayload")] + DeleteRow = 52, + + #[event(input = "RowIdentifierPayload")] + DuplicateRow = 53, + #[event(input = "CellIdentifierPayload", output = "Cell")] GetCell = 70, 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 d9cfbac578..10bee819ce 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 @@ -39,6 +39,8 @@ pub enum GridEvent { ApplySelectOptionChangeset = 32, CreateRow = 50, GetRow = 51, + DeleteRow = 52, + DuplicateRow = 53, GetCell = 70, UpdateCell = 71, ApplySelectOptionCellChangeset = 72, @@ -65,6 +67,8 @@ impl ::protobuf::ProtobufEnum for GridEvent { 32 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), + 52 => ::std::option::Option::Some(GridEvent::DeleteRow), + 53 => ::std::option::Option::Some(GridEvent::DuplicateRow), 70 => ::std::option::Option::Some(GridEvent::GetCell), 71 => ::std::option::Option::Some(GridEvent::UpdateCell), 72 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), @@ -88,6 +92,8 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::ApplySelectOptionChangeset, GridEvent::CreateRow, GridEvent::GetRow, + GridEvent::DeleteRow, + GridEvent::DuplicateRow, GridEvent::GetCell, GridEvent::UpdateCell, GridEvent::ApplySelectOptionCellChangeset, @@ -119,15 +125,16 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xde\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xff\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\ lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x1e\n\ \x1aApplySelectOptionChangeset\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\ - \x06GetRow\x103\x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\ - \"\n\x1eApplySelectOptionCellChangeset\x10Hb\x06proto3\ + \x06GetRow\x103\x12\r\n\tDeleteRow\x104\x12\x10\n\x0cDuplicateRow\x105\ + \x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\"\n\x1eApplySe\ + lectOptionCellChangeset\x10Hb\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 1201bd759e..9fad8dd7b1 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 @@ -15,6 +15,8 @@ enum GridEvent { ApplySelectOptionChangeset = 32; CreateRow = 50; GetRow = 51; + DeleteRow = 52; + DuplicateRow = 53; GetCell = 70; UpdateCell = 71; ApplySelectOptionCellChangeset = 72; From d08f298fb6a2eb2ef1665fc9999958f1d152f4cb Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 9 Apr 2022 22:42:42 +0800 Subject: [PATCH 122/179] chore: rename structs --- frontend/rust-lib/flowy-grid/src/event_handler.rs | 14 ++++++++++---- .../flowy-grid/src/services/block_meta_manager.rs | 10 +++++----- .../flowy-grid/src/services/grid_editor.rs | 12 ++++++++++++ .../flowy-grid/src/services/row/row_loader.rs | 12 ++++++------ 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index d94753c4b0..1ac3796059 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -183,16 +183,22 @@ pub(crate) async fn get_row_handler( pub(crate) async fn delete_row_handler( data: Data, manager: AppData>, -) -> DataResult { - todo!() +) -> Result<(), FlowyError> { + let params: RowIdentifier = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.delete_row(¶ms.row_id)?; + Ok(()) } #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn duplicate_row_handler( data: Data, manager: AppData>, -) -> DataResult { - todo!() +) -> Result<(), FlowyError> { + let params: RowIdentifier = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.duplicate_row(¶ms.row_id)?; + Ok(()) } #[tracing::instrument(level = "debug", skip(data, manager), err)] diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 104b6fbbdb..54e223c242 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -2,7 +2,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::ClientGridBlockMetaEditor; use crate::services::persistence::block_index::BlockIndexPersistence; -use crate::services::row::{make_block_row_ids, make_rows_from_row_metas, GridBlockSnapshot}; +use crate::services::row::{make_block_rows, make_rows_from_row_metas, GridBlockSnapshot}; use dashmap::DashMap; use flowy_error::FlowyResult; @@ -94,11 +94,11 @@ impl GridBlockMetaEditorManager { pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { let mut changesets = vec![]; - for block_row_ids in make_block_row_ids(&row_orders) { - let editor = self.get_editor(&block_row_ids.block_id).await?; - let row_count = editor.delete_rows(block_row_ids.row_ids).await?; + for block_row in make_block_rows(&row_orders) { + let editor = self.get_editor(&block_row.block_id).await?; + let row_count = editor.delete_rows(block_row.row_ids).await?; - let changeset = GridBlockMetaChangeset::from_row_count(&block_row_ids.block_id, row_count); + let changeset = GridBlockMetaChangeset::from_row_count(&block_row.block_id, row_count); changesets.push(changeset); } 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 b934d4bc35..1753013760 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -267,6 +267,13 @@ impl ClientGridEditor { } } } + pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> { + todo!() + } + + pub async fn duplicate_row(&self, row_id: &str) -> FlowyResult<()> { + todo!() + } pub async fn get_cell(&self, params: &CellIdentifier) -> Option { let field_meta = self.get_field_meta(¶ms.field_id).await?; @@ -316,6 +323,11 @@ impl ClientGridEditor { Ok(grid_blocks) } + // pub async fn get_field_metas(&self, field_ids: Option>) -> FlowyResult> + // where + // T: Into, + // { + pub async fn delete_rows(&self, row_orders: Vec) -> FlowyResult<()> { let changesets = self.block_meta_manager.delete_rows(row_orders).await?; for changeset in changesets { diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 89f7db216c..ac26f1d32c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -8,14 +8,14 @@ use std::collections::HashMap; use std::sync::Arc; -pub(crate) struct BlockRowIds { +pub(crate) struct BlockRows { pub(crate) block_id: String, pub(crate) row_ids: Vec, } -impl BlockRowIds { +impl BlockRows { pub fn new(block_id: &str) -> Self { - BlockRowIds { + BlockRows { block_id: block_id.to_owned(), row_ids: vec![], } @@ -27,13 +27,13 @@ pub struct GridBlockSnapshot { pub row_metas: Vec>, } -pub(crate) fn make_block_row_ids(row_orders: &[RowOrder]) -> Vec { - let mut map: HashMap<&String, BlockRowIds> = HashMap::new(); +pub(crate) fn make_block_rows(row_orders: &[RowOrder]) -> Vec { + let mut map: HashMap<&String, BlockRows> = HashMap::new(); row_orders.iter().for_each(|row_order| { let block_id = &row_order.block_id; let row_id = row_order.row_id.clone(); map.entry(block_id) - .or_insert_with(|| BlockRowIds::new(block_id)) + .or_insert_with(|| BlockRows::new(block_id)) .row_ids .push(row_id); }); From b92660058ca7c428be6f23fa3dc3e671453703ec Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 07:10:15 +0800 Subject: [PATCH 123/179] chore: remove grid block from dart side --- .../workspace/application/grid/grid_bloc.dart | 2 +- .../application/grid/grid_service.dart | 10 +---- .../plugins/grid/src/grid_page.dart | 37 +++++++++++++------ frontend/rust-lib/flowy-grid/src/manager.rs | 4 +- .../src/entities/meta.rs | 8 ++-- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- .../src/client_grid/grid_block_meta_pad.rs | 10 ++--- .../src/client_grid/grid_builder.rs | 4 +- .../src/client_grid/grid_meta_pad.rs | 26 ++++++------- 9 files changed, 51 insertions(+), 54 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 a46136a6b5..9e563e2d4e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -79,7 +79,7 @@ class GridBloc extends Bloc { } Future _loadGrid(Emitter emit) async { - final result = await service.openGrid(gridId: view.id); + final result = await service.loadGrid(gridId: view.id); return Future( () => result.fold( (grid) async => await _loadFields(grid, emit), 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 9bb2e36e5f..3456007a6c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -5,7 +5,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; class GridService { - Future> openGrid({required String gridId}) async { + Future> loadGrid({required String gridId}) async { await FolderEventSetLatestView(ViewId(value: gridId)).send(); final payload = GridId(value: gridId); @@ -18,14 +18,6 @@ class GridService { return GridEventCreateRow(payload).send(); } - Future> getGridBlocks( - {required String gridId, required List blockOrders}) { - final payload = QueryGridBlocksPayload.create() - ..gridId = gridId - ..blockOrders.addAll(blockOrders); - return GridEventGetGridBlocks(payload).send(); - } - Future> getFields({required String gridId, required List fieldOrders}) { final payload = QueryFieldPayload.create() ..gridId = gridId 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 b96b89ba2e..6ff3852de5 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 @@ -155,24 +155,37 @@ class _FlowyGridState extends State { return rowChanged; }, builder: (context, state) { - return SliverAnimatedList( - key: _key, - initialItemCount: context.read().state.rows.length, - itemBuilder: (BuildContext context, int index, Animation animation) { + return SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) { final blockRow = context.read().state.rows[index]; final fields = context.read().state.fields; final rowData = RowData.fromBlockRow(blockRow, fields); - return _renderRow(rowData, animation); + return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)); }, - ); + childCount: context.read().state.rows.length, + addRepaintBoundaries: true, + addAutomaticKeepAlives: true, + )); + + // return SliverAnimatedList( + // key: _key, + // initialItemCount: context.read().state.rows.length, + // itemBuilder: (BuildContext context, int index, Animation animation) { + // final blockRow = context.read().state.rows[index]; + // final fields = context.read().state.fields; + // final rowData = RowData.fromBlockRow(blockRow, fields); + // return _renderRow(rowData, animation); + // }, + // ); }, ); } - Widget _renderRow(RowData rowData, Animation animation) { - return SizeTransition( - sizeFactor: animation, - child: GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)), - ); - } + // Widget _renderRow(RowData rowData, Animation animation) { + // return SizeTransition( + // sizeFactor: animation, + // child: GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)), + // ); + // } } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index d35ad334c9..21106351c6 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -179,7 +179,7 @@ pub async fn make_grid_view_data( let grid_meta = GridMeta { grid_id: view_id.to_string(), fields: build_context.field_metas, - block_metas: vec![build_context.block_metas], + blocks: vec![build_context.block_metas], }; // Create grid @@ -190,7 +190,7 @@ pub async fn make_grid_view_data( let _ = grid_manager.create_grid(view_id, repeated_revision).await?; // Indexing the block's rows - build_context.block_meta_data.row_metas.iter().for_each(|row| { + build_context.block_meta_data.rows.iter().for_each(|row| { let _ = grid_manager .block_index_persistence .insert_or_update(&row.block_id, &row.id); diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index a7354d3668..7ccd96e955 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -18,7 +18,7 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub block_metas: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] @@ -74,7 +74,7 @@ pub struct GridBlockMetaData { pub block_id: String, #[pb(index = 2)] - pub row_metas: Vec, + pub rows: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, Eq, PartialEq)] @@ -398,7 +398,7 @@ impl std::convert::From for RowMetaChangeset { row_id: changeset.row_id, height: None, visibility: None, - cell_by_field_id: cell_by_field_id, + cell_by_field_id, } } } @@ -420,7 +420,7 @@ impl std::default::Default for BuildGridContext { let grid_block = GridBlockMeta::new(); let grid_block_meta_data = GridBlockMetaData { block_id: grid_block.block_id.clone(), - row_metas: vec![], + rows: vec![], }; Self { 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 15367cc5ac..0847950b98 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -7,7 +7,7 @@ fn grid_serde_test() { let grid = GridMeta { grid_id, fields, - block_metas: vec![], + blocks: vec![], }; let grid_1_json = serde_json::to_string(&grid).unwrap(); @@ -24,7 +24,7 @@ fn grid_default_serde_test() { let grid = GridMeta { grid_id, fields: vec![], - block_metas: vec![], + blocks: vec![], }; let json = serde_json::to_string(&grid).unwrap(); diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 11cb625762..ce2802052e 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -30,11 +30,7 @@ impl GridBlockMetaPad { CollaborateError::internal().context(msg) })?; let block_id = meta_data.block_id; - let rows = meta_data - .row_metas - .into_iter() - .map(Arc::new) - .collect::>>(); + let rows = meta_data.rows.into_iter().map(Arc::new).collect::>>(); Ok(Self { block_id, row_metas: rows, @@ -215,13 +211,13 @@ impl std::default::Default for GridBlockMetaPad { fn default() -> Self { let block_meta_data = GridBlockMetaData { block_id: uuid(), - row_metas: vec![], + rows: vec![], }; let delta = make_block_meta_delta(&block_meta_data); GridBlockMetaPad { block_id: block_meta_data.block_id, - row_metas: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), + row_metas: block_meta_data.rows.into_iter().map(Arc::new).collect::>(), delta, } } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs index 43b85de269..d9c5d17280 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs @@ -14,7 +14,7 @@ impl GridBuilder { pub fn add_empty_row(mut self) -> Self { let row = RowMeta::new(&self.build_context.block_metas.block_id); - self.build_context.block_meta_data.row_metas.push(row); + self.build_context.block_meta_data.rows.push(row); self.build_context.block_metas.row_count += 1; self } @@ -57,7 +57,7 @@ mod tests { let grid_meta = GridMeta { grid_id, fields: build_context.field_metas, - block_metas: vec![build_context.block_metas], + blocks: vec![build_context.block_metas], }; let grid_meta_delta = make_grid_delta(&grid_meta); diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 8329d9cc9c..e9788e802d 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -235,12 +235,12 @@ impl GridMetaPad { pub fn create_block_meta(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid_meta| { - if grid_meta.block_metas.iter().any(|b| b.block_id == block.block_id) { + if grid_meta.blocks.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { - match grid_meta.block_metas.last() { - None => grid_meta.block_metas.push(block), + match grid_meta.blocks.last() { + None => grid_meta.blocks.push(block), Some(last_block) => { if last_block.start_row_index > block.start_row_index && last_block.len() > block.start_row_index @@ -248,7 +248,7 @@ impl GridMetaPad { let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string(); return Err(CollaborateError::internal().context(msg)) } - grid_meta.block_metas.push(block); + grid_meta.blocks.push(block); } } Ok(Some(())) @@ -257,7 +257,7 @@ impl GridMetaPad { } pub fn get_block_metas(&self) -> Vec { - self.grid_meta.block_metas.clone() + self.grid_meta.blocks.clone() } pub fn update_block_meta(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { @@ -320,19 +320,15 @@ impl GridMetaPad { where F: FnOnce(&mut GridBlockMeta) -> CollaborateResult>, { - self.modify_grid(|grid_meta| { - match grid_meta - .block_metas - .iter() - .position(|block| block.block_id == block_id) - { + self.modify_grid( + |grid_meta| match grid_meta.blocks.iter().position(|block| block.block_id == block_id) { None => { tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); Ok(None) } - Some(index) => f(&mut grid_meta.block_metas[index]), - } - }) + Some(index) => f(&mut grid_meta.blocks[index]), + }, + ) } pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> @@ -380,7 +376,7 @@ impl std::default::Default for GridMetaPad { let grid = GridMeta { grid_id: uuid(), fields: vec![], - block_metas: vec![], + blocks: vec![], }; let delta = make_grid_delta(&grid); GridMetaPad { From a755d523719b3bedb1757362ff4f13d67f1492cf Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 08:25:01 +0800 Subject: [PATCH 124/179] chore: using cow for row ids stuff --- .../app_flowy/lib/startup/deps_resolver.dart | 2 +- .../workspace/application/grid/grid_bloc.dart | 45 ++++--- .../application/grid/grid_listener.dart | 42 +++++++ .../application/grid/grid_service.dart | 2 +- .../flowy-grid-data-model/grid.pb.dart | 8 ++ .../flowy-grid-data-model/grid.pbjson.dart | 3 +- .../flowy-grid-data-model/meta.pb.dart | 20 +-- .../flowy-grid-data-model/meta.pbjson.dart | 8 +- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- .../src/services/block_meta_editor.rs | 20 ++- .../src/services/block_meta_manager.rs | 79 +++++------- .../flowy-grid/src/services/grid_editor.rs | 23 ++-- .../flowy-grid/src/services/row/row_loader.rs | 33 ++--- .../src/entities/grid.rs | 12 +- .../src/protobuf/model/grid.rs | 100 +++++++++++---- .../src/protobuf/model/meta.rs | 118 +++++++++--------- .../src/protobuf/proto/grid.proto | 1 + .../src/protobuf/proto/meta.proto | 4 +- .../src/client_grid/grid_block_meta_pad.rs | 36 ++++-- 19 files changed, 331 insertions(+), 229 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 5f69ab1ad4..98ab00d0e4 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -148,7 +148,7 @@ void _resolveDocDeps(GetIt getIt) { void _resolveGridDeps(GetIt getIt) { // Grid getIt.registerFactoryParam( - (view, _) => GridBloc(view: view, service: GridService()), + (view, _) => GridBloc(view: view), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 9e563e2d4e..c68cd8c726 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -9,27 +9,31 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'grid_block_service.dart'; import 'field/grid_listenr.dart'; +import 'grid_listener.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final View view; - final GridService service; + final GridService _gridService; + final GridListener _gridListener; final GridFieldsListener _fieldListener; - GridBlockService? _blockService; - GridBloc({required this.view, required this.service}) + GridBloc({required this.view}) : _fieldListener = GridFieldsListener(gridId: view.id), + _gridService = GridService(), + _gridListener = GridListener(gridId: view.id), super(GridState.initial()) { on( (event, emit) async { await event.map( initial: (InitialGrid value) async { await _initGrid(emit); + _startListening(); }, createRow: (_CreateRow value) { - service.createRow(gridId: view.id); + _gridService.createRow(gridId: view.id); }, delete: (_Delete value) {}, rename: (_Rename value) {}, @@ -48,7 +52,7 @@ class GridBloc extends Bloc { @override Future close() async { await _fieldListener.stop(); - await _blockService?.stop(); + await _gridListener.stop(); return super.close(); } @@ -64,22 +68,17 @@ class GridBloc extends Bloc { await _loadGrid(emit); } - Future _initGridBlock(Grid grid) async { - _blockService = GridBlockService( - gridId: grid.id, - blockOrders: grid.blockOrders, - ); - - _blockService?.blocksUpdateNotifier?.addPublishListener((result) { - result.fold( - (blockMap) => add(GridEvent.didReceiveRowUpdate(_buildRows(blockMap))), - (err) => Log.error('$err'), - ); + void _startListening() { + _gridListener.rowsUpdateNotifier.addPublishListener((result) { + result.fold((blockOrders) { + add(GridEvent.didReceiveRowUpdate(_buildRows(blockOrders))); + }, (err) => Log.error(err)); }); + _gridListener.start(); } Future _loadGrid(Emitter emit) async { - final result = await service.loadGrid(gridId: view.id); + final result = await _gridService.loadGrid(gridId: view.id); return Future( () => result.fold( (grid) async => await _loadFields(grid, emit), @@ -89,14 +88,14 @@ class GridBloc extends Bloc { } Future _loadFields(Grid grid, Emitter emit) async { - final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); + final result = await _gridService.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); return Future( () => result.fold( (fields) { - _initGridBlock(grid); emit(state.copyWith( grid: Some(grid), fields: fields.items, + rows: _buildRows(grid.blockOrders), loadingState: GridLoadingState.finish(left(unit)), )); }, @@ -105,17 +104,17 @@ class GridBloc extends Bloc { ); } - List _buildRows(GridBlockMap blockMap) { + List _buildRows(List blockOrders) { List rows = []; - blockMap.forEach((_, GridBlock gridBlock) { - rows.addAll(gridBlock.rowOrders.map( + for (final blockOrder in blockOrders) { + rows.addAll(blockOrder.rowOrders.map( (rowOrder) => GridBlockRow( gridId: view.id, rowId: rowOrder.rowId, height: rowOrder.height.toDouble(), ), )); - }); + } return rows; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart new file mode 100644 index 0000000000..b2917089c8 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -0,0 +1,42 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; + +class GridListener { + final String gridId; + PublishNotifier, FlowyError>> rowsUpdateNotifier = PublishNotifier(comparable: null); + GridNotificationListener? _listener; + + GridListener({required this.gridId}); + + void start() { + _listener = GridNotificationListener( + objectId: gridId, + handler: _handler, + ); + } + + void _handler(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.DidUpdateBlock: + result.fold( + (payload) => rowsUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]), + (error) => rowsUpdateNotifier.value = right(error), + ); + break; + + default: + break; + } + } + + Future stop() async { + await _listener?.stop(); + rowsUpdateNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 3456007a6c..bf558cb574 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -5,7 +5,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; class GridService { - Future> loadGrid({required String gridId}) async { + Future> loadGrid({required String gridId}) async { await FolderEventSetLatestView(ViewId(value: gridId)).send(); final payload = GridId(value: gridId); 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 e27e019be3..c5e0fb28c9 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 @@ -803,17 +803,22 @@ class RepeatedGridBlock extends $pb.GeneratedMessage { class GridBlockOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false ; GridBlockOrder._() : super(); factory GridBlockOrder({ $core.String? blockId, + $core.Iterable? rowOrders, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } + if (rowOrders != null) { + _result.rowOrders.addAll(rowOrders); + } return _result; } factory GridBlockOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -845,6 +850,9 @@ class GridBlockOrder extends $pb.GeneratedMessage { $core.bool hasBlockId() => $_has(0); @$pb.TagNumber(1) void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rowOrders => $_getList(1); } class GridBlock 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 3cd228af79..676025d66a 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 @@ -165,11 +165,12 @@ const GridBlockOrder$json = const { '1': 'GridBlockOrder', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'row_orders', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZA=='); +final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIoCgpyb3dfb3JkZXJzGAIgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index d322e644c0..9e0f08d42a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blockMetas, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage { if (fields != null) { _result.fields.addAll(fields); } - if (blockMetas != null) { - _result.blockMetas.addAll(blockMetas); + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } @@ -73,7 +73,7 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blockMetas => $_getList(2); + $core.List get blocks => $_getList(2); } class GridBlockMeta extends $pb.GeneratedMessage { @@ -154,21 +154,21 @@ class GridBlockMeta extends $pb.GeneratedMessage { class GridBlockMetaData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..hasRequiredFields = false ; GridBlockMetaData._() : super(); factory GridBlockMetaData({ $core.String? blockId, - $core.Iterable? rowMetas, + $core.Iterable? rows, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rowMetas != null) { - _result.rowMetas.addAll(rowMetas); + if (rows != null) { + _result.rows.addAll(rows); } return _result; } @@ -203,7 +203,7 @@ class GridBlockMetaData extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List get rowMetas => $_getList(1); + $core.List get rows => $_getList(1); } class FieldMeta extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 71b0c1b8e0..70180c231d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,12 +29,12 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, - const {'1': 'block_metas', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSLwoLYmxvY2tfbWV0YXMYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgpibG9ja01ldGFz'); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz'); @$core.Deprecated('Use gridBlockMetaDescriptor instead') const GridBlockMeta$json = const { '1': 'GridBlockMeta', @@ -52,12 +52,12 @@ const GridBlockMetaData$json = const { '1': 'GridBlockMetaData', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'}, + const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, ], }; /// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw=='); +final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIcCgRyb3dzGAIgAygLMgguUm93TWV0YVIEcm93cw=='); @$core.Deprecated('Use fieldMetaDescriptor instead') const FieldMeta$json = const { '1': 'FieldMeta', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 1ac3796059..acc1eeb5c6 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -186,7 +186,7 @@ pub(crate) async fn delete_row_handler( ) -> Result<(), FlowyError> { let params: RowIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let _ = editor.delete_row(¶ms.row_id)?; + let _ = editor.delete_row(¶ms.row_id).await?; Ok(()) } @@ -197,7 +197,7 @@ pub(crate) async fn duplicate_row_handler( ) -> Result<(), FlowyError> { let params: RowIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let _ = editor.duplicate_row(¶ms.row_id)?; + let _ = editor.duplicate_row(¶ms.row_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 8518a70fb0..1f8e2e2006 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -7,6 +7,7 @@ use flowy_sync::entities::revision::Revision; use flowy_sync::util::make_delta_from_revisions; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; +use std::borrow::Cow; use std::sync::Arc; use tokio::sync::RwLock; @@ -54,11 +55,11 @@ impl ClientGridBlockMetaEditor { Ok(row_count) } - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult { + pub async fn delete_rows(&self, ids: Vec>) -> FlowyResult { let mut row_count = 0; let _ = self .modify(|pad| { - let changeset = pad.delete_rows(&ids)?; + let changeset = pad.delete_rows(ids)?; row_count = pad.number_of_rows(); Ok(changeset) }) @@ -71,17 +72,24 @@ impl ClientGridBlockMetaEditor { Ok(()) } - pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { - let row_metas = self.pad.read().await.get_row_metas(&row_ids)?; + pub async fn get_row_metas(&self, row_ids: Option>>) -> FlowyResult>> + where + T: AsRef + ToOwned + ?Sized, + { + let row_metas = self.pad.read().await.get_row_metas(row_ids)?; Ok(row_metas) } - pub async fn get_cell_metas(&self, field_id: &str, row_ids: &Option>) -> FlowyResult> { + pub async fn get_cell_metas( + &self, + field_id: &str, + row_ids: Option>>, + ) -> FlowyResult> { let cell_metas = self.pad.read().await.get_cell_metas(field_id, row_ids)?; Ok(cell_metas) } - pub async fn get_row_orders(&self, row_ids: &Option>) -> FlowyResult> { + pub async fn get_row_orders(&self, row_ids: Option>>) -> FlowyResult> { let row_orders = self .pad .read() diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 54e223c242..b14f6641f3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -2,7 +2,8 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::ClientGridBlockMetaEditor; use crate::services::persistence::block_index::BlockIndexPersistence; -use crate::services::row::{make_block_rows, make_rows_from_row_metas, GridBlockSnapshot}; +use crate::services::row::{group_row_orders, make_rows_from_row_metas, GridBlockSnapshot}; +use std::borrow::Cow; use dashmap::DashMap; use flowy_error::FlowyResult; @@ -18,6 +19,7 @@ use std::sync::Arc; pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, + // Key: block_id editor_map: DashMap>, persistence: Arc, } @@ -92,19 +94,6 @@ impl GridBlockMetaEditorManager { Ok(changesets) } - pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { - let mut changesets = vec![]; - for block_row in make_block_rows(&row_orders) { - let editor = self.get_editor(&block_row.block_id).await?; - let row_count = editor.delete_rows(block_row.row_ids).await?; - - let changeset = GridBlockMetaChangeset::from_row_count(&block_row.block_id, row_count); - changesets.push(changeset); - } - - Ok(changesets) - } - pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; @@ -112,6 +101,23 @@ impl GridBlockMetaEditorManager { Ok(()) } + pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { + let mut changesets = vec![]; + for block_order in group_row_orders(row_orders) { + let editor = self.get_editor(&block_order.block_id).await?; + let row_ids = block_order + .row_orders + .into_iter() + .map(|row_order| Cow::Owned(row_order.row_id)) + .collect::>>(); + let row_count = editor.delete_rows(row_ids).await?; + let changeset = GridBlockMetaChangeset::from_row_count(&block_order.block_id, row_count); + changesets.push(changeset); + } + + Ok(changesets) + } + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { let row_id = changeset.row_id.clone(); let editor = self.get_editor_from_row_id(&row_id).await?; @@ -130,7 +136,7 @@ impl GridBlockMetaEditorManager { pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult>> { let editor = self.get_editor_from_row_id(row_id).await?; - let row_ids = vec![row_id.to_owned()]; + let row_ids = vec![Cow::Borrowed(row_id)]; let mut row_metas = editor.get_row_metas(Some(row_ids)).await?; if row_metas.is_empty() { Ok(None) @@ -139,11 +145,16 @@ impl GridBlockMetaEditorManager { } } + pub async fn get_row_orders(&self, block_id: &str) -> FlowyResult> { + let editor = self.get_editor(block_id).await?; + editor.get_row_orders(None).await + } + pub(crate) async fn make_block_snapshots(&self, block_ids: Vec) -> FlowyResult> { let mut snapshots = vec![]; for block_id in block_ids { let editor = self.get_editor(&block_id).await?; - let row_metas = editor.get_row_metas(None).await?; + let row_metas = editor.get_row_metas::<&str>(None).await?; snapshots.push(GridBlockSnapshot { block_id, row_metas }); } Ok(snapshots) @@ -155,22 +166,22 @@ impl GridBlockMetaEditorManager { &self, block_ids: Vec, field_id: &str, - row_ids: Option>, + row_ids: Option>>, ) -> FlowyResult> { let mut block_cell_metas = vec![]; for block_id in block_ids { let editor = self.get_editor(&block_id).await?; - let cell_metas = editor.get_cell_metas(field_id, &row_ids).await?; + let cell_metas = editor.get_cell_metas(field_id, row_ids.clone()).await?; block_cell_metas.extend(cell_metas); } Ok(block_cell_metas) } async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { - let block_order: GridBlockOrder = block_id.into(); - send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock) - .payload(block_order) - .send(); + // let block_order: GridBlockOrder = block_id.into(); + // send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock) + // .payload(block_order) + // .send(); Ok(()) } @@ -196,30 +207,6 @@ impl GridBlockMetaEditorManager { } } Ok(()) - - // - // let field_meta_map = field_metas - // .iter() - // .map(|field_meta| (&field_meta.id, field_meta)) - // .collect::>(); - // - // let mut cells = vec![]; - // changeset - // .cell_by_field_id - // .into_iter() - // .for_each( - // |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) { - // None => {} - // Some((_, cell)) => cells.push(cell), - // }, - // ); - // - // if !cells.is_empty() { - // send_dart_notification(&changeset.row_id, GridNotification::DidUpdateRow) - // .payload(RepeatedCell::from(cells)) - // .send(); - // } - // Ok(()) } } 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 1753013760..44fc4c4e76 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -337,17 +337,18 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> FlowyResult { - let field_orders = self.pad.read().await.get_field_orders(); - let block_orders = self - .pad - .read() - .await - .get_block_metas() - .into_iter() - .map(|grid_block_meta| GridBlockOrder { - block_id: grid_block_meta.block_id, - }) - .collect::>(); + let pad_read_guard = self.pad.read().await; + let field_orders = pad_read_guard.get_field_orders(); + let mut block_orders = vec![]; + for block_order in pad_read_guard.get_block_metas() { + let row_orders = self.block_meta_manager.get_row_orders(&block_order.block_id).await?; + let block_order = GridBlockOrder { + block_id: block_order.block_id, + row_orders, + }; + block_orders.push(block_order); + } + Ok(Grid { id: self.grid_id.clone(), field_orders, diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index ac26f1d32c..26e889f1af 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,41 +1,28 @@ use crate::services::row::decode_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, Row, RowMeta, RowOrder, + Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; -pub(crate) struct BlockRows { - pub(crate) block_id: String, - pub(crate) row_ids: Vec, -} - -impl BlockRows { - pub fn new(block_id: &str) -> Self { - BlockRows { - block_id: block_id.to_owned(), - row_ids: vec![], - } - } -} - pub struct GridBlockSnapshot { pub(crate) block_id: String, pub row_metas: Vec>, } -pub(crate) fn make_block_rows(row_orders: &[RowOrder]) -> Vec { - let mut map: HashMap<&String, BlockRows> = HashMap::new(); - row_orders.iter().for_each(|row_order| { - let block_id = &row_order.block_id; - let row_id = row_order.row_id.clone(); +pub(crate) fn group_row_orders(row_orders: Vec) -> Vec { + let mut map: HashMap = HashMap::new(); + row_orders.into_iter().for_each(|row_order| { + // Memory Optimization: escape clone block_id + let block_id = row_order.block_id.clone(); map.entry(block_id) - .or_insert_with(|| BlockRows::new(block_id)) - .row_ids - .push(row_id); + .or_insert_with(|| GridBlockOrder::new(&row_order.block_id)) + .row_orders + .push(row_order); }); map.into_values().collect::>() } 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 d3cb9f7f69..42b3453d20 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -260,11 +260,17 @@ impl std::convert::From> for RepeatedGridBlock { pub struct GridBlockOrder { #[pb(index = 1)] pub block_id: String, + + #[pb(index = 2)] + pub row_orders: Vec, } -impl std::convert::From<&str> for GridBlockOrder { - fn from(s: &str) -> Self { - GridBlockOrder { block_id: s.to_owned() } +impl GridBlockOrder { + pub fn new(block_id: &str) -> Self { + GridBlockOrder { + block_id: block_id.to_owned(), + row_orders: 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 c31a2def27..944db183f9 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 @@ -2715,6 +2715,7 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedGridBlock { pub struct GridBlockOrder { // message fields pub block_id: ::std::string::String, + pub row_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2756,10 +2757,40 @@ impl GridBlockOrder { pub fn take_block_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } + + // repeated .RowOrder row_orders = 2; + + + pub fn get_row_orders(&self) -> &[RowOrder] { + &self.row_orders + } + pub fn clear_row_orders(&mut self) { + self.row_orders.clear(); + } + + // Param is passed by value, moved + pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { + self.row_orders = v; + } + + // Mutable pointer to the field. + pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_orders + } + + // Take field + pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) + } } impl ::protobuf::Message for GridBlockOrder { fn is_initialized(&self) -> bool { + for v in &self.row_orders { + if !v.is_initialized() { + return false; + } + }; true } @@ -2770,6 +2801,9 @@ impl ::protobuf::Message for GridBlockOrder { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -2785,6 +2819,10 @@ impl ::protobuf::Message for GridBlockOrder { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } + for value in &self.row_orders { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2794,6 +2832,11 @@ impl ::protobuf::Message for GridBlockOrder { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } + for v in &self.row_orders { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2837,6 +2880,11 @@ impl ::protobuf::Message for GridBlockOrder { |m: &GridBlockOrder| { &m.block_id }, |m: &mut GridBlockOrder| { &mut m.block_id }, )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_orders", + |m: &GridBlockOrder| { &m.row_orders }, + |m: &mut GridBlockOrder| { &mut m.row_orders }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlockOrder", fields, @@ -2854,6 +2902,7 @@ impl ::protobuf::Message for GridBlockOrder { impl ::protobuf::Clear for GridBlockOrder { fn clear(&mut self) { self.block_id.clear(); + self.row_orders.clear(); self.unknown_fields.clear(); } } @@ -5283,31 +5332,32 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ - items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\ - \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ - \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ - \x07content\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07\ - fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07co\ - ntent\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\ - \x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05i\ - tems\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04\ - name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"\ - #\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\ - \x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13on\ - e_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\ - \x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\ - \x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\ - \x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cst\ - artFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\ - \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\ - \x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16Qu\ - eryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblo\ - ckOrdersb\x06proto3\ + items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\ + \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"E\n\tGridBlock\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ + 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ + \"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ + \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\ + \x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepe\ + atedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\ + \n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\ + \x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\ + \x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10\ + CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of\ + _start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.\ + FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etype\ + OptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartField\ + IdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ + \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ + locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ + \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ + sb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index f90832a447..8ca8db2765 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub block_metas: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .GridBlockMeta block_metas = 3; + // repeated .GridBlockMeta blocks = 3; - pub fn get_block_metas(&self) -> &[GridBlockMeta] { - &self.block_metas + pub fn get_blocks(&self) -> &[GridBlockMeta] { + &self.blocks } - pub fn clear_block_metas(&mut self) { - self.block_metas.clear(); + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_block_metas(&mut self, v: ::protobuf::RepeatedField) { - self.block_metas = v; + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - pub fn mut_block_metas(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.block_metas + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_block_metas(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.block_metas, ::protobuf::RepeatedField::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta { return false; } }; - for v in &self.block_metas { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_metas)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.block_metas { + for value in &self.blocks { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.block_metas { + for v in &self.blocks { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -241,9 +241,9 @@ impl ::protobuf::Message for GridMeta { |m: &mut GridMeta| { &mut m.fields }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "block_metas", - |m: &GridMeta| { &m.block_metas }, - |m: &mut GridMeta| { &mut m.block_metas }, + "blocks", + |m: &GridMeta| { &m.blocks }, + |m: &mut GridMeta| { &mut m.blocks }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridMeta", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta { fn clear(&mut self) { self.grid_id.clear(); self.fields.clear(); - self.block_metas.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } @@ -513,7 +513,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { pub struct GridBlockMetaData { // message fields pub block_id: ::std::string::String, - pub row_metas: ::protobuf::RepeatedField, + pub rows: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -556,35 +556,35 @@ impl GridBlockMetaData { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .RowMeta row_metas = 2; + // repeated .RowMeta rows = 2; - pub fn get_row_metas(&self) -> &[RowMeta] { - &self.row_metas + pub fn get_rows(&self) -> &[RowMeta] { + &self.rows } - pub fn clear_row_metas(&mut self) { - self.row_metas.clear(); + pub fn clear_rows(&mut self) { + self.rows.clear(); } // Param is passed by value, moved - pub fn set_row_metas(&mut self, v: ::protobuf::RepeatedField) { - self.row_metas = v; + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; } // Mutable pointer to the field. - pub fn mut_row_metas(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.row_metas + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows } // Take field - pub fn take_row_metas(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.row_metas, ::protobuf::RepeatedField::new()) + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for GridBlockMetaData { fn is_initialized(&self) -> bool { - for v in &self.row_metas { + for v in &self.rows { if !v.is_initialized() { return false; } @@ -600,7 +600,7 @@ impl ::protobuf::Message for GridBlockMetaData { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_metas)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -617,7 +617,7 @@ impl ::protobuf::Message for GridBlockMetaData { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.row_metas { + for value in &self.rows { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -630,7 +630,7 @@ impl ::protobuf::Message for GridBlockMetaData { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.row_metas { + for v in &self.rows { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -679,9 +679,9 @@ impl ::protobuf::Message for GridBlockMetaData { |m: &mut GridBlockMetaData| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "row_metas", - |m: &GridBlockMetaData| { &m.row_metas }, - |m: &mut GridBlockMetaData| { &mut m.row_metas }, + "rows", + |m: &GridBlockMetaData| { &m.rows }, + |m: &mut GridBlockMetaData| { &mut m.rows }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlockMetaData", @@ -700,7 +700,7 @@ impl ::protobuf::Message for GridBlockMetaData { impl ::protobuf::Clear for GridBlockMetaData { fn clear(&mut self) { self.block_id.clear(); - self.row_metas.clear(); + self.rows.clear(); self.unknown_fields.clear(); } } @@ -3453,26 +3453,26 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"x\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ - s\x12/\n\x0bblock_metas\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\nblockM\ - etas\"o\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\ - ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ - \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMet\ - aData\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_m\ - etas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xbc\x02\n\tFieldMe\ - ta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ - \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ - \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ - \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ - \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ - idth\x12>\n\x0ctype_options\x18\x08\x20\x03(\x0b2\x1b.FieldMeta.TypeOpti\ - onsEntryR\x0btypeOptions\x1a>\n\x10TypeOptionsEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\ - \x028\x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\ - \x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06\ - gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04des\ - c\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\ + s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\ + \n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ + \x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\ + \n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"L\n\x11GridBlockMetaDat\ + a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\ + \x18\x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xbc\x02\n\tFieldMeta\x12\ + \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01\ + (\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield\ + _type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\ + \x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\ + \x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12>\ + \n\x0ctype_options\x18\x08\x20\x03(\x0b2\x1b.FieldMeta.TypeOptionsEntryR\ + \x0btypeOptions\x1a>\n\x10TypeOptionsEntry\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\x028\ + \x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\ + \x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06grid\ + Id\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\ + \x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\ \x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\ \x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nv\ isibility\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\ 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 c1166a3ae1..b1bf045cd7 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 @@ -57,6 +57,7 @@ message RepeatedGridBlock { } message GridBlockOrder { string block_id = 1; + repeated RowOrder row_orders = 2; } message GridBlock { string id = 1; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 18c05896fe..2cf0f9b2af 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,7 +3,7 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated FieldMeta fields = 2; - repeated GridBlockMeta block_metas = 3; + repeated GridBlockMeta blocks = 3; } message GridBlockMeta { string block_id = 1; @@ -12,7 +12,7 @@ message GridBlockMeta { } message GridBlockMetaData { string block_id = 1; - repeated RowMeta row_metas = 2; + repeated RowMeta rows = 2; } message FieldMeta { string id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index ce2802052e..bd5ea1d1a6 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -5,6 +5,7 @@ use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowM use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; +use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; @@ -67,38 +68,48 @@ impl GridBlockMetaPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: Vec>) -> CollaborateResult> { self.modify(|rows| { - rows.retain(|row| !row_ids.contains(&row.id)); + rows.retain(|row| !row_ids.contains(&Cow::Borrowed(&row.id))); Ok(Some(())) }) } - pub fn get_row_metas(&self, row_ids: &Option>) -> CollaborateResult>> { + pub fn get_row_metas(&self, row_ids: Option>>) -> CollaborateResult>> + where + T: AsRef + ToOwned + ?Sized, + { match row_ids { None => Ok(self.row_metas.to_vec()), Some(row_ids) => { let row_map = self .row_metas .iter() - .map(|row| (&row.id, row.clone())) - .collect::>>(); + .map(|row| (row.id.as_str(), row.clone())) + .collect::>>(); Ok(row_ids .iter() - .flat_map(|row_id| match row_map.get(row_id) { - None => { - tracing::error!("Can't find the row with id: {}", row_id); - None + .flat_map(|row_id| { + let row_id = row_id.as_ref().as_ref(); + match row_map.get(row_id) { + None => { + tracing::error!("Can't find the row with id: {}", row_id); + None + } + Some(row) => Some(row.clone()), } - Some(row) => Some(row.clone()), }) .collect::>()) } } } - pub fn get_cell_metas(&self, field_id: &str, row_ids: &Option>) -> CollaborateResult> { + pub fn get_cell_metas( + &self, + field_id: &str, + row_ids: Option>>, + ) -> CollaborateResult> { let rows = self.get_row_metas(row_ids)?; let cell_metas = rows .iter() @@ -227,6 +238,7 @@ impl std::default::Default for GridBlockMetaPad { mod tests { use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; + use std::borrow::Cow; #[test] fn block_meta_add_row() { @@ -331,7 +343,7 @@ mod tests { }; let _ = pad.add_row_meta(row.clone(), None).unwrap().unwrap(); - let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); + let change = pad.delete_rows(vec![Cow::Borrowed(&row.id)]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":29},{"delete":77},{"retain":2}]"# From 420b8ca05dcc27a50158bbddb08ec78b05cea0c4 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 10:31:55 +0800 Subject: [PATCH 125/179] chore: fix deserialize GridBlockMetaPad error --- .../workspace/application/grid/grid_bloc.dart | 13 +- .../application/grid/grid_block_service.dart | 92 ----- .../application/grid/grid_listener.dart | 7 +- .../flowy-grid-data-model/grid.pb.dart | 71 ++++ .../flowy-grid-data-model/grid.pbjson.dart | 13 + .../flowy-grid-data-model/meta.pb.dart | 18 +- .../flowy-grid-data-model/meta.pbjson.dart | 4 +- .../flowy-grid/dart_notification.pbenum.dart | 4 +- .../flowy-grid/dart_notification.pbjson.dart | 4 +- .../flowy-grid/src/dart_notification.rs | 2 +- frontend/rust-lib/flowy-grid/src/manager.rs | 5 +- .../src/protobuf/model/dart_notification.rs | 16 +- .../protobuf/proto/dart_notification.proto | 2 +- .../src/services/block_meta_manager.rs | 41 +- .../src/entities/grid.rs | 44 +++ .../src/entities/meta.rs | 12 +- .../src/protobuf/model/grid.rs | 358 ++++++++++++++++-- .../src/protobuf/model/meta.rs | 63 ++- .../src/protobuf/proto/grid.proto | 6 + .../src/protobuf/proto/meta.proto | 2 +- .../src/client_grid/grid_block_meta_pad.rs | 53 ++- .../src/client_grid/grid_builder.rs | 6 +- 22 files changed, 605 insertions(+), 231 deletions(-) delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_block_service.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 index c68cd8c726..44c048bac3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -7,7 +7,6 @@ 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_block_service.dart'; import 'field/grid_listenr.dart'; import 'grid_listener.dart'; import 'grid_service.dart'; @@ -70,8 +69,16 @@ class GridBloc extends Bloc { void _startListening() { _gridListener.rowsUpdateNotifier.addPublishListener((result) { - result.fold((blockOrders) { - add(GridEvent.didReceiveRowUpdate(_buildRows(blockOrders))); + result.fold((gridBlockChangeset) { + for (final changeset in gridBlockChangeset) { + if (changeset.insertedRows.isNotEmpty) {} + + if (changeset.deletedRows.isNotEmpty) {} + + if (changeset.updatedRows.isNotEmpty) {} + } + + // add(GridEvent.didReceiveRowUpdate(_buildRows(blockOrders))); }, (err) => Log.error(err)); }); _gridListener.start(); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart deleted file mode 100644 index e6ecad0949..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'dart:collection'; -import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; -import 'package:flowy_infra/notifier.dart'; -import 'dart:async'; -import 'dart:typed_data'; -import 'package:app_flowy/core/notification_helper.dart'; - -typedef GridBlockMap = LinkedHashMap; -typedef BlocksUpdateNotifierValue = Either; - -class GridBlockService { - String gridId; - GridBlockMap blockMap = GridBlockMap(); - late GridBlockListener _blockListener; - PublishNotifier? blocksUpdateNotifier = PublishNotifier(); - - GridBlockService({required this.gridId, required List blockOrders}) { - _loadGridBlocks(blockOrders); - - _blockListener = GridBlockListener(gridId: gridId); - _blockListener.blockUpdateNotifier.addPublishListener((result) { - result.fold( - (blockOrder) => _loadGridBlocks(blockOrder), - (err) => Log.error(err), - ); - }); - _blockListener.start(); - } - - Future stop() async { - await _blockListener.stop(); - blocksUpdateNotifier?.dispose(); - blocksUpdateNotifier = null; - } - - void _loadGridBlocks(List blockOrders) { - final payload = QueryGridBlocksPayload.create() - ..gridId = gridId - ..blockOrders.addAll(blockOrders); - - GridEventGetGridBlocks(payload).send().then((result) { - result.fold( - (repeatedBlocks) { - for (final gridBlock in repeatedBlocks.items) { - blockMap[gridBlock.id] = gridBlock; - } - blocksUpdateNotifier?.value = left(blockMap); - }, - (err) => blocksUpdateNotifier?.value = right(err), - ); - }); - } -} - -class GridBlockListener { - final String gridId; - PublishNotifier, FlowyError>> blockUpdateNotifier = PublishNotifier(comparable: null); - GridNotificationListener? _listener; - - GridBlockListener({required this.gridId}); - - void start() { - _listener = GridNotificationListener( - objectId: gridId, - handler: _handler, - ); - } - - void _handler(GridNotification ty, Either result) { - switch (ty) { - case GridNotification.DidUpdateBlock: - result.fold( - (payload) => blockUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]), - (error) => blockUpdateNotifier.value = right(error), - ); - break; - - default: - break; - } - } - - Future stop() async { - await _listener?.stop(); - blockUpdateNotifier.dispose(); - } -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index b2917089c8..f36a630e1a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -9,7 +9,8 @@ import 'package:app_flowy/core/notification_helper.dart'; class GridListener { final String gridId; - PublishNotifier, FlowyError>> rowsUpdateNotifier = PublishNotifier(comparable: null); + PublishNotifier, FlowyError>> rowsUpdateNotifier = + PublishNotifier(comparable: null); GridNotificationListener? _listener; GridListener({required this.gridId}); @@ -23,9 +24,9 @@ class GridListener { void _handler(GridNotification ty, Either result) { switch (ty) { - case GridNotification.DidUpdateBlock: + case GridNotification.DidUpdateGridBlock: result.fold( - (payload) => rowsUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]), + (payload) => rowsUpdateNotifier.value = left([GridBlockOrderChangeset.fromBuffer(payload)]), (error) => rowsUpdateNotifier.value = right(error), ); break; 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 c5e0fb28c9..f613504047 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 @@ -855,6 +855,77 @@ class GridBlockOrder extends $pb.GeneratedMessage { $core.List get rowOrders => $_getList(1); } +class GridBlockOrderChangeset extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrderChangeset', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..hasRequiredFields = false + ; + + GridBlockOrderChangeset._() : super(); + factory GridBlockOrderChangeset({ + $core.String? blockId, + $core.Iterable? insertedRows, + $core.Iterable? deletedRows, + $core.Iterable? updatedRows, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (insertedRows != null) { + _result.insertedRows.addAll(insertedRows); + } + if (deletedRows != null) { + _result.deletedRows.addAll(deletedRows); + } + if (updatedRows != null) { + _result.updatedRows.addAll(updatedRows); + } + return _result; + } + factory GridBlockOrderChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockOrderChangeset.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') + GridBlockOrderChangeset clone() => GridBlockOrderChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockOrderChangeset copyWith(void Function(GridBlockOrderChangeset) updates) => super.copyWith((message) => updates(message as GridBlockOrderChangeset)) as GridBlockOrderChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockOrderChangeset create() => GridBlockOrderChangeset._(); + GridBlockOrderChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockOrderChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockOrderChangeset? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get insertedRows => $_getList(1); + + @$pb.TagNumber(3) + $core.List get deletedRows => $_getList(2); + + @$pb.TagNumber(4) + $core.List get updatedRows => $_getList(3); +} + class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') 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 676025d66a..0c1abf778e 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 @@ -171,6 +171,19 @@ const GridBlockOrder$json = const { /// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIoCgpyb3dfb3JkZXJzGAIgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); +@$core.Deprecated('Use gridBlockOrderChangesetDescriptor instead') +const GridBlockOrderChangeset$json = const { + '1': 'GridBlockOrderChangeset', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'insertedRows'}, + const {'1': 'deleted_rows', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'deletedRows'}, + const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.RowOrder', '10': 'updatedRows'}, + ], +}; + +/// Descriptor for `GridBlockOrderChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockOrderChangesetDescriptor = $convert.base64Decode('ChdHcmlkQmxvY2tPcmRlckNoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIuCg1pbnNlcnRlZF9yb3dzGAIgAygLMgkuUm93T3JkZXJSDGluc2VydGVkUm93cxIsCgxkZWxldGVkX3Jvd3MYAyADKAsyCS5Sb3dPcmRlclILZGVsZXRlZFJvd3MSLAoMdXBkYXRlZF9yb3dzGAQgAygLMgkuUm93T3JkZXJSC3VwZGF0ZWRSb3dz'); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 9e0f08d42a..5ab811fa3f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -1014,7 +1014,7 @@ class CellMetaChangeset extends $pb.GeneratedMessage { class BuildGridContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', subBuilder: GridBlockMeta.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMeta', subBuilder: GridBlockMeta.create) ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaData.create) ..hasRequiredFields = false ; @@ -1022,15 +1022,15 @@ class BuildGridContext extends $pb.GeneratedMessage { BuildGridContext._() : super(); factory BuildGridContext({ $core.Iterable? fieldMetas, - GridBlockMeta? blockMetas, + GridBlockMeta? blockMeta, GridBlockMetaData? blockMetaData, }) { final _result = create(); if (fieldMetas != null) { _result.fieldMetas.addAll(fieldMetas); } - if (blockMetas != null) { - _result.blockMetas = blockMetas; + if (blockMeta != null) { + _result.blockMeta = blockMeta; } if (blockMetaData != null) { _result.blockMetaData = blockMetaData; @@ -1062,15 +1062,15 @@ class BuildGridContext extends $pb.GeneratedMessage { $core.List get fieldMetas => $_getList(0); @$pb.TagNumber(2) - GridBlockMeta get blockMetas => $_getN(1); + GridBlockMeta get blockMeta => $_getN(1); @$pb.TagNumber(2) - set blockMetas(GridBlockMeta v) { setField(2, v); } + set blockMeta(GridBlockMeta v) { setField(2, v); } @$pb.TagNumber(2) - $core.bool hasBlockMetas() => $_has(1); + $core.bool hasBlockMeta() => $_has(1); @$pb.TagNumber(2) - void clearBlockMetas() => clearField(2); + void clearBlockMeta() => clearField(2); @$pb.TagNumber(2) - GridBlockMeta ensureBlockMetas() => $_ensure(1); + GridBlockMeta ensureBlockMeta() => $_ensure(1); @$pb.TagNumber(3) GridBlockMetaData get blockMetaData => $_getN(2); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 70180c231d..8e73d2ce1c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -208,10 +208,10 @@ const BuildGridContext$json = const { '1': 'BuildGridContext', '2': const [ const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, - const {'1': 'block_metas', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, + const {'1': 'block_meta', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMeta'}, const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'blockMetaData'}, ], }; /// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi8KC2Jsb2NrX21ldGFzGAIgASgLMg4uR3JpZEJsb2NrTWV0YVIKYmxvY2tNZXRhcxI6Cg9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVINYmxvY2tNZXRhRGF0YQ=='); +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmJsb2NrX21ldGEYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglibG9ja01ldGESOgoPYmxvY2tfbWV0YV9kYXRhGAMgASgLMhIuR3JpZEJsb2NrTWV0YURhdGFSDWJsb2NrTWV0YURhdGE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 4331fef2a7..d39002e540 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -12,7 +12,7 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock'); - static const GridNotification DidUpdateBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateBlock'); + static const GridNotification DidUpdateGridBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridBlock'); static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); static const GridNotification DidUpdateCell = GridNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateCell'); static const GridNotification DidUpdateGrid = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGrid'); @@ -21,7 +21,7 @@ class GridNotification extends $pb.ProtobufEnum { static const $core.List values = [ Unknown, DidCreateBlock, - DidUpdateBlock, + DidUpdateGridBlock, DidUpdateRow, DidUpdateCell, DidUpdateGrid, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index ed6bbdc2d4..787a77ffa1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -14,7 +14,7 @@ const GridNotification$json = const { '2': const [ const {'1': 'Unknown', '2': 0}, const {'1': 'DidCreateBlock', '2': 11}, - const {'1': 'DidUpdateBlock', '2': 20}, + const {'1': 'DidUpdateGridBlock', '2': 20}, const {'1': 'DidUpdateRow', '2': 30}, const {'1': 'DidUpdateCell', '2': 31}, const {'1': 'DidUpdateGrid', '2': 40}, @@ -23,4 +23,4 @@ const GridNotification$json = const { }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEQoNRGlkVXBkYXRlQ2VsbBAfEhEKDURpZFVwZGF0ZUdyaWQQKBISCg5EaWRVcGRhdGVGaWVsZBAp'); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhYKEkRpZFVwZGF0ZUdyaWRCbG9jaxAUEhAKDERpZFVwZGF0ZVJvdxAeEhEKDURpZFVwZGF0ZUNlbGwQHxIRCg1EaWRVcGRhdGVHcmlkECgSEgoORGlkVXBkYXRlRmllbGQQKQ=='); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index cc910e30c6..a2a1de0a9f 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -6,7 +6,7 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; pub enum GridNotification { Unknown = 0, DidCreateBlock = 11, - DidUpdateBlock = 20, + DidUpdateGridBlock = 20, DidUpdateRow = 30, DidUpdateCell = 31, DidUpdateGrid = 40, diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 21106351c6..9f8d0c77e1 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -110,6 +110,7 @@ impl GridManager { } } + #[tracing::instrument(level = "trace", skip(self, pool), err)] async fn make_grid_editor( &self, grid_id: &str, @@ -175,11 +176,11 @@ pub async fn make_grid_view_data( grid_manager: Arc, build_context: BuildGridContext, ) -> FlowyResult { - let block_id = build_context.block_metas.block_id.clone(); + let block_id = build_context.block_meta.block_id.clone(); let grid_meta = GridMeta { grid_id: view_id.to_string(), fields: build_context.field_metas, - blocks: vec![build_context.block_metas], + blocks: vec![build_context.block_meta], }; // Create grid diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index d5eaa2a6d8..326ae3ef4e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -27,7 +27,7 @@ pub enum GridNotification { Unknown = 0, DidCreateBlock = 11, - DidUpdateBlock = 20, + DidUpdateGridBlock = 20, DidUpdateRow = 30, DidUpdateCell = 31, DidUpdateGrid = 40, @@ -43,7 +43,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), 11 => ::std::option::Option::Some(GridNotification::DidCreateBlock), - 20 => ::std::option::Option::Some(GridNotification::DidUpdateBlock), + 20 => ::std::option::Option::Some(GridNotification::DidUpdateGridBlock), 30 => ::std::option::Option::Some(GridNotification::DidUpdateRow), 31 => ::std::option::Option::Some(GridNotification::DidUpdateCell), 40 => ::std::option::Option::Some(GridNotification::DidUpdateGrid), @@ -56,7 +56,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { static values: &'static [GridNotification] = &[ GridNotification::Unknown, GridNotification::DidCreateBlock, - GridNotification::DidUpdateBlock, + GridNotification::DidUpdateGridBlock, GridNotification::DidUpdateRow, GridNotification::DidUpdateCell, GridNotification::DidUpdateGrid, @@ -89,11 +89,11 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x93\x01\n\x10GridNotification\x12\x0b\n\ - \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x12\n\x0eDidUp\ - dateBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUpdate\ - Cell\x10\x1f\x12\x11\n\rDidUpdateGrid\x10(\x12\x12\n\x0eDidUpdateField\ - \x10)b\x06proto3\ + \n\x17dart_notification.proto*\x97\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x16\n\x12DidUp\ + dateGridBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUp\ + dateCell\x10\x1f\x12\x11\n\rDidUpdateGrid\x10(\x12\x12\n\x0eDidUpdateFie\ + ld\x10)b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index cbda705483..20cf529f3e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -3,7 +3,7 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; DidCreateBlock = 11; - DidUpdateBlock = 20; + DidUpdateGridBlock = 20; DidUpdateRow = 30; DidUpdateCell = 31; DidUpdateGrid = 40; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index b14f6641f3..1fcddbd4da 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -9,7 +9,7 @@ use dashmap::DashMap; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, - GridBlockOrder, RowMeta, RowMetaChangeset, RowOrder, + GridBlockOrder, GridBlockOrderChangeset, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{RevisionManager, RevisionPersistence}; @@ -70,8 +70,12 @@ impl GridBlockMetaEditorManager { ) -> FlowyResult { let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?; let editor = self.get_editor(&row_meta.block_id).await?; + let row_order = RowOrder::from(&row_meta); let row_count = editor.create_row(row_meta, start_row_id).await?; - self.notify_block_did_update_row(block_id).await?; + + let _ = self + .notify_block_did_update_row(GridBlockOrderChangeset::from_update(block_id, vec![row_order])) + .await?; Ok(row_count) } @@ -81,14 +85,18 @@ impl GridBlockMetaEditorManager { ) -> FlowyResult> { let mut changesets = vec![]; for (block_id, row_metas) in rows_by_block_id { + let mut inserted_row_orders = vec![]; let editor = self.get_editor(&block_id).await?; let mut row_count = 0; - for row in &row_metas { + for row in row_metas { let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; - row_count = editor.create_row(row.clone(), None).await?; + inserted_row_orders.push(RowOrder::from(&row)); + row_count = editor.create_row(row, None).await?; } changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); - let _ = self.notify_block_did_update_row(&block_id).await?; + let _ = self + .notify_block_did_update_row(GridBlockOrderChangeset::from_insert(&block_id, inserted_row_orders)) + .await?; } Ok(changesets) @@ -97,7 +105,19 @@ impl GridBlockMetaEditorManager { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - let _ = self.notify_block_did_update_row(&editor.block_id).await?; + + match editor + .get_row_orders(Some(vec![Cow::Borrowed(&changeset.row_id)])) + .await? + .pop() + { + None => {} + Some(row_order) => { + let block_order_changeset = GridBlockOrderChangeset::from_update(&editor.block_id, vec![row_order]); + let _ = self.notify_block_did_update_row(block_order_changeset).await?; + } + } + Ok(()) } @@ -177,11 +197,10 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> { - // let block_order: GridBlockOrder = block_id.into(); - // send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock) - // .payload(block_order) - // .send(); + async fn notify_block_did_update_row(&self, changeset: GridBlockOrderChangeset) -> FlowyResult<()> { + send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock) + .payload(changeset) + .send(); 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 42b3453d20..9f09e4e975 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -274,6 +274,50 @@ impl GridBlockOrder { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct GridBlockOrderChangeset { + #[pb(index = 1)] + pub block_id: String, + + #[pb(index = 2)] + pub inserted_rows: Vec, + + #[pb(index = 3)] + pub deleted_rows: Vec, + + #[pb(index = 4)] + pub updated_rows: Vec, +} + +impl GridBlockOrderChangeset { + pub fn from_insert(block_id: &str, inserted_rows: Vec) -> Self { + Self { + block_id: block_id.to_owned(), + inserted_rows, + deleted_rows: vec![], + updated_rows: vec![], + } + } + + pub fn from_delete(block_id: &str, deleted_rows: Vec) -> Self { + Self { + block_id: block_id.to_owned(), + inserted_rows: vec![], + deleted_rows, + updated_rows: vec![], + } + } + + pub fn from_update(block_id: &str, updated_rows: Vec) -> Self { + Self { + block_id: block_id.to_owned(), + inserted_rows: vec![], + deleted_rows: vec![], + updated_rows, + } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 7ccd96e955..b78b166802 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -409,7 +409,7 @@ pub struct BuildGridContext { pub field_metas: Vec, #[pb(index = 2)] - pub block_metas: GridBlockMeta, + pub block_meta: GridBlockMeta, #[pb(index = 3)] pub block_meta_data: GridBlockMetaData, @@ -417,16 +417,16 @@ pub struct BuildGridContext { impl std::default::Default for BuildGridContext { fn default() -> Self { - let grid_block = GridBlockMeta::new(); - let grid_block_meta_data = GridBlockMetaData { - block_id: grid_block.block_id.clone(), + let block_meta = GridBlockMeta::new(); + let block_meta_data = GridBlockMetaData { + block_id: block_meta.block_id.clone(), rows: vec![], }; Self { field_metas: vec![], - block_metas: grid_block, - block_meta_data: grid_block_meta_data, + block_meta, + block_meta_data, } } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 944db183f9..44c51f4a21 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 @@ -2919,6 +2919,312 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockOrderChangeset { + // message fields + pub block_id: ::std::string::String, + pub inserted_rows: ::protobuf::RepeatedField, + pub deleted_rows: ::protobuf::RepeatedField, + pub updated_rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockOrderChangeset { + fn default() -> &'a GridBlockOrderChangeset { + ::default_instance() + } +} + +impl GridBlockOrderChangeset { + pub fn new() -> GridBlockOrderChangeset { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // repeated .RowOrder inserted_rows = 2; + + + pub fn get_inserted_rows(&self) -> &[RowOrder] { + &self.inserted_rows + } + pub fn clear_inserted_rows(&mut self) { + self.inserted_rows.clear(); + } + + // Param is passed by value, moved + pub fn set_inserted_rows(&mut self, v: ::protobuf::RepeatedField) { + self.inserted_rows = v; + } + + // Mutable pointer to the field. + pub fn mut_inserted_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.inserted_rows + } + + // Take field + pub fn take_inserted_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.inserted_rows, ::protobuf::RepeatedField::new()) + } + + // repeated .RowOrder deleted_rows = 3; + + + pub fn get_deleted_rows(&self) -> &[RowOrder] { + &self.deleted_rows + } + pub fn clear_deleted_rows(&mut self) { + self.deleted_rows.clear(); + } + + // Param is passed by value, moved + pub fn set_deleted_rows(&mut self, v: ::protobuf::RepeatedField) { + self.deleted_rows = v; + } + + // Mutable pointer to the field. + pub fn mut_deleted_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.deleted_rows + } + + // Take field + pub fn take_deleted_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.deleted_rows, ::protobuf::RepeatedField::new()) + } + + // repeated .RowOrder updated_rows = 4; + + + pub fn get_updated_rows(&self) -> &[RowOrder] { + &self.updated_rows + } + pub fn clear_updated_rows(&mut self) { + self.updated_rows.clear(); + } + + // Param is passed by value, moved + pub fn set_updated_rows(&mut self, v: ::protobuf::RepeatedField) { + self.updated_rows = v; + } + + // Mutable pointer to the field. + pub fn mut_updated_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.updated_rows + } + + // Take field + pub fn take_updated_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.updated_rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlockOrderChangeset { + fn is_initialized(&self) -> bool { + for v in &self.inserted_rows { + if !v.is_initialized() { + return false; + } + }; + for v in &self.deleted_rows { + if !v.is_initialized() { + return false; + } + }; + for v in &self.updated_rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.inserted_rows)?; + }, + 3 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.deleted_rows)?; + }, + 4 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.updated_rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + for value in &self.inserted_rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.deleted_rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.updated_rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + for v in &self.inserted_rows { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.deleted_rows { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.updated_rows { + 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() -> GridBlockOrderChangeset { + GridBlockOrderChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlockOrderChangeset| { &m.block_id }, + |m: &mut GridBlockOrderChangeset| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "inserted_rows", + |m: &GridBlockOrderChangeset| { &m.inserted_rows }, + |m: &mut GridBlockOrderChangeset| { &mut m.inserted_rows }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "deleted_rows", + |m: &GridBlockOrderChangeset| { &m.deleted_rows }, + |m: &mut GridBlockOrderChangeset| { &mut m.deleted_rows }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "updated_rows", + |m: &GridBlockOrderChangeset| { &m.updated_rows }, + |m: &mut GridBlockOrderChangeset| { &mut m.updated_rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockOrderChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockOrderChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockOrderChangeset::new) + } +} + +impl ::protobuf::Clear for GridBlockOrderChangeset { + fn clear(&mut self) { + self.block_id.clear(); + self.inserted_rows.clear(); + self.deleted_rows.clear(); + self.updated_rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockOrderChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockOrderChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GridBlock { // message fields @@ -5334,30 +5640,34 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\ \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\ - \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"E\n\tGridBlock\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ - 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ - \"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ - \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\ - \x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepe\ - atedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\ - \n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\ - \x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\ - \x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10\ - CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ - \"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of\ - _start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.\ - FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etype\ - OptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartField\ - IdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ - \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ - locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ - \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ - sb\x06proto3\ + \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc0\x01\n\x17GridBlockOr\ + derChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12.\n\ + \rinserted_rows\x18\x02\x20\x03(\x0b2\t.RowOrderR\x0cinsertedRows\x12,\n\ + \x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\ + \x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"E\n\t\ + GridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\ + \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08\ + field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\ + \x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07gri\ + d_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01\ + (\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\ + \n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\ + \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ + \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ + R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ + lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ + \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ + idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ + \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ + rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ + \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ + \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ + \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ + ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ + ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ + \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ + ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ + \x0bblockOrdersb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 8ca8db2765..3468eb594d 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -3114,7 +3114,7 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { pub struct BuildGridContext { // message fields pub field_metas: ::protobuf::RepeatedField, - pub block_metas: ::protobuf::SingularPtrField, + pub block_meta: ::protobuf::SingularPtrField, pub block_meta_data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -3157,37 +3157,37 @@ impl BuildGridContext { ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) } - // .GridBlockMeta block_metas = 2; + // .GridBlockMeta block_meta = 2; - pub fn get_block_metas(&self) -> &GridBlockMeta { - self.block_metas.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_block_meta(&self) -> &GridBlockMeta { + self.block_meta.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_block_metas(&mut self) { - self.block_metas.clear(); + pub fn clear_block_meta(&mut self) { + self.block_meta.clear(); } - pub fn has_block_metas(&self) -> bool { - self.block_metas.is_some() + pub fn has_block_meta(&self) -> bool { + self.block_meta.is_some() } // Param is passed by value, moved - pub fn set_block_metas(&mut self, v: GridBlockMeta) { - self.block_metas = ::protobuf::SingularPtrField::some(v); + pub fn set_block_meta(&mut self, v: GridBlockMeta) { + self.block_meta = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_block_metas(&mut self) -> &mut GridBlockMeta { - if self.block_metas.is_none() { - self.block_metas.set_default(); + pub fn mut_block_meta(&mut self) -> &mut GridBlockMeta { + if self.block_meta.is_none() { + self.block_meta.set_default(); } - self.block_metas.as_mut().unwrap() + self.block_meta.as_mut().unwrap() } // Take field - pub fn take_block_metas(&mut self) -> GridBlockMeta { - self.block_metas.take().unwrap_or_else(|| GridBlockMeta::new()) + pub fn take_block_meta(&mut self) -> GridBlockMeta { + self.block_meta.take().unwrap_or_else(|| GridBlockMeta::new()) } // .GridBlockMetaData block_meta_data = 3; @@ -3231,7 +3231,7 @@ impl ::protobuf::Message for BuildGridContext { return false; } }; - for v in &self.block_metas { + for v in &self.block_meta { if !v.is_initialized() { return false; } @@ -3252,7 +3252,7 @@ impl ::protobuf::Message for BuildGridContext { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_metas)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta)?; }, 3 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta_data)?; @@ -3273,7 +3273,7 @@ impl ::protobuf::Message for BuildGridContext { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - if let Some(ref v) = self.block_metas.as_ref() { + if let Some(ref v) = self.block_meta.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -3292,7 +3292,7 @@ impl ::protobuf::Message for BuildGridContext { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - if let Some(ref v) = self.block_metas.as_ref() { + if let Some(ref v) = self.block_meta.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)?; @@ -3346,9 +3346,9 @@ impl ::protobuf::Message for BuildGridContext { |m: &mut BuildGridContext| { &mut m.field_metas }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "block_metas", - |m: &BuildGridContext| { &m.block_metas }, - |m: &mut BuildGridContext| { &mut m.block_metas }, + "block_meta", + |m: &BuildGridContext| { &m.block_meta }, + |m: &mut BuildGridContext| { &mut m.block_meta }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "block_meta_data", @@ -3372,7 +3372,7 @@ impl ::protobuf::Message for BuildGridContext { impl ::protobuf::Clear for BuildGridContext { fn clear(&mut self) { self.field_metas.clear(); - self.block_metas.clear(); + self.block_meta.clear(); self.block_meta_data.clear(); self.unknown_fields.clear(); } @@ -3498,14 +3498,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06\ gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\ - \tH\0R\x04dataB\r\n\x0bone_of_data\"\xac\x01\n\x10BuildGridContext\x12+\ - \n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\ - \x0bblock_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12\ - :\n\x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\rblo\ - ckMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ - \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ - \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ - o3\ + \tH\0R\x04dataB\r\n\x0bone_of_data\"\xaa\x01\n\x10BuildGridContext\x12+\ + \n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ + \nblock_meta\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tblockMeta\x12:\n\ + \x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\rblockM\ + etaData*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 b1bf045cd7..8c1b48e7a4 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 @@ -59,6 +59,12 @@ message GridBlockOrder { string block_id = 1; repeated RowOrder row_orders = 2; } +message GridBlockOrderChangeset { + string block_id = 1; + repeated RowOrder inserted_rows = 2; + repeated RowOrder deleted_rows = 3; + repeated RowOrder updated_rows = 4; +} message GridBlock { string id = 1; repeated RowOrder row_orders = 2; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 2cf0f9b2af..dcc8d5f91c 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -63,7 +63,7 @@ message CellMetaChangeset { } message BuildGridContext { repeated FieldMeta field_metas = 1; - GridBlockMeta block_metas = 2; + GridBlockMeta block_meta = 2; GridBlockMetaData block_meta_data = 3; } enum FieldType { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index bd5ea1d1a6..f416b55141 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -16,7 +16,7 @@ pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct GridBlockMetaPad { block_id: String, - row_metas: Vec>, + rows: Vec>, #[serde(skip)] pub(crate) delta: GridBlockMetaDelta, @@ -32,11 +32,7 @@ impl GridBlockMetaPad { })?; let block_id = meta_data.block_id; let rows = meta_data.rows.into_iter().map(Arc::new).collect::>>(); - Ok(Self { - block_id, - row_metas: rows, - delta, - }) + Ok(Self { block_id, rows, delta }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { @@ -80,10 +76,10 @@ impl GridBlockMetaPad { T: AsRef + ToOwned + ?Sized, { match row_ids { - None => Ok(self.row_metas.to_vec()), + None => Ok(self.rows.to_vec()), Some(row_ids) => { let row_map = self - .row_metas + .rows .iter() .map(|row| (row.id.as_str(), row.clone())) .collect::>>(); @@ -122,7 +118,7 @@ impl GridBlockMetaPad { } pub fn number_of_rows(&self) -> i32 { - self.row_metas.len() as i32 + self.rows.len() as i32 } pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { @@ -155,7 +151,7 @@ impl GridBlockMetaPad { F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { let cloned_self = self.clone(); - match f(&mut self.row_metas)? { + match f(&mut self.rows)? { None => Ok(None), Some(_) => { let old = cloned_self.to_json()?; @@ -228,7 +224,7 @@ impl std::default::Default for GridBlockMetaPad { let delta = make_block_meta_delta(&block_meta_data); GridBlockMetaPad { block_id: block_meta_data.block_id, - row_metas: block_meta_data.rows.into_iter().map(Arc::new).collect::>(), + rows: block_meta_data.rows.into_iter().map(Arc::new).collect::>(), delta, } } @@ -254,7 +250,7 @@ mod tests { let change = pad.add_row_meta(row, None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); } @@ -268,24 +264,24 @@ mod tests { let change = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":106},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":90},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row_meta(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":114},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# + r#"[{"retain":157},{"insert":",{\"id\":\"3\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); - assert_eq!(*pad.row_metas[0], row_1); - assert_eq!(*pad.row_metas[1], row_3); - assert_eq!(*pad.row_metas[2], row_2); + assert_eq!(*pad.rows[0], row_1); + assert_eq!(*pad.rows[1], row_2); + assert_eq!(*pad.rows[2], row_3); } fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { @@ -309,9 +305,9 @@ mod tests { let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row_meta(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); - assert_eq!(*pad.row_metas[0], row_3); - assert_eq!(*pad.row_metas[1], row_1); - assert_eq!(*pad.row_metas[2], row_2); + assert_eq!(*pad.rows[0], row_3); + assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[2], row_2); } #[test] @@ -325,9 +321,9 @@ mod tests { let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row_meta(row_3.clone(), Some("".to_string())).unwrap().unwrap(); - assert_eq!(*pad.row_metas[0], row_3); - assert_eq!(*pad.row_metas[1], row_1); - assert_eq!(*pad.row_metas[2], row_2); + assert_eq!(*pad.rows[0], row_3); + assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[2], row_2); } #[test] @@ -346,7 +342,7 @@ mod tests { let change = pad.delete_rows(vec![Cow::Borrowed(&row.id)]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":29},{"delete":77},{"retain":2}]"# + r#"[{"retain":24},{"delete":66},{"retain":2}]"# ); assert_eq!(pad.delta_str(), pre_delta_str); @@ -375,18 +371,17 @@ mod tests { assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":85},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# + r#"[{"retain":69},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# ); assert_eq!( pad.to_json().unwrap(), - r#"{"block_id":"1","row_metas":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# + r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cells":{},"height":100,"visibility":true}]}"# ); } fn test_pad() -> GridBlockMetaPad { - let delta = - GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"row_metas\":[]}"}]"#).unwrap(); + let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); GridBlockMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs index d9c5d17280..7a1e140140 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs @@ -13,9 +13,9 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.build_context.block_metas.block_id); + let row = RowMeta::new(&self.build_context.block_meta.block_id); self.build_context.block_meta_data.rows.push(row); - self.build_context.block_metas.row_count += 1; + self.build_context.block_meta.row_count += 1; self } @@ -57,7 +57,7 @@ mod tests { let grid_meta = GridMeta { grid_id, fields: build_context.field_metas, - blocks: vec![build_context.block_metas], + blocks: vec![build_context.block_meta], }; let grid_meta_delta = make_grid_delta(&grid_meta); From f01d3250ae1201e83479d73914d8e5ea60352f5d Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 14:24:12 +0800 Subject: [PATCH 126/179] chore: reload after delete or insert row --- .../workspace/application/grid/grid_bloc.dart | 67 ++-- .../application/grid/row/row_service.dart | 15 +- .../plugins/grid/src/grid_page.dart | 8 +- .../src/widgets/row/row_action_sheet.dart | 23 +- .../flowy-grid-data-model/grid.pb.dart | 82 ++++- .../flowy-grid-data-model/grid.pbjson.dart | 18 +- .../src/services/block_meta_editor.rs | 22 +- .../src/services/block_meta_manager.rs | 36 ++- .../field/type_options/date_type_option.rs | 2 +- .../type_options/selection_type_option.rs | 8 +- .../flowy-grid/src/services/grid_editor.rs | 9 +- .../flowy-grid/src/services/row/row_loader.rs | 2 +- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../src/entities/grid.rs | 26 +- .../src/protobuf/model/grid.rs | 304 ++++++++++++++++-- .../src/protobuf/proto/grid.proto | 6 +- .../src/client_grid/grid_block_meta_pad.rs | 20 +- 17 files changed, 533 insertions(+), 117 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 44c048bac3..bf56b9d864 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -34,8 +34,6 @@ class GridBloc extends Bloc { createRow: (_CreateRow value) { _gridService.createRow(gridId: view.id); }, - delete: (_Delete value) {}, - rename: (_Rename value) {}, updateDesc: (_Desc value) {}, didReceiveRowUpdate: (_DidReceiveRowUpdate value) { emit(state.copyWith(rows: value.rows)); @@ -71,14 +69,18 @@ class GridBloc extends Bloc { _gridListener.rowsUpdateNotifier.addPublishListener((result) { result.fold((gridBlockChangeset) { for (final changeset in gridBlockChangeset) { - if (changeset.insertedRows.isNotEmpty) {} + if (changeset.insertedRows.isNotEmpty) { + _insertRows(changeset.insertedRows); + } - if (changeset.deletedRows.isNotEmpty) {} + if (changeset.deletedRows.isNotEmpty) { + _deleteRows(changeset.deletedRows); + } - if (changeset.updatedRows.isNotEmpty) {} + if (changeset.updatedRows.isNotEmpty) { + _updateRows(changeset.updatedRows); + } } - - // add(GridEvent.didReceiveRowUpdate(_buildRows(blockOrders))); }, (err) => Log.error(err)); }); _gridListener.start(); @@ -111,29 +113,50 @@ class GridBloc extends Bloc { ); } - List _buildRows(List blockOrders) { - List rows = []; - for (final blockOrder in blockOrders) { - rows.addAll(blockOrder.rowOrders.map( - (rowOrder) => GridBlockRow( - gridId: view.id, - rowId: rowOrder.rowId, - height: rowOrder.height.toDouble(), - ), - )); + void _deleteRows(List deletedRows) { + final List rows = List.from(state.rows); + rows.retainWhere( + (row) => deletedRows.where((deletedRow) => deletedRow.rowId == row.rowId).isEmpty, + ); + + add(GridEvent.didReceiveRowUpdate(rows)); + } + + void _insertRows(List createdRows) { + final List rows = List.from(state.rows); + for (final newRow in createdRows) { + if (newRow.hasIndex()) { + rows.insert(newRow.index, newRow.rowOrder); + } else { + rows.add(newRow.rowOrder); + } } - return rows; + add(GridEvent.didReceiveRowUpdate(rows)); + } + + void _updateRows(List updatedRows) { + final List rows = List.from(state.rows); + for (final updatedRow in updatedRows) { + final index = rows.indexWhere((row) => row.rowId == updatedRow.rowId); + if (index != -1) { + rows.removeAt(index); + rows.insert(index, updatedRow); + } + } + add(GridEvent.didReceiveRowUpdate(rows)); + } + + List _buildRows(List blockOrders) { + return blockOrders.expand((blockOrder) => blockOrder.rowOrders).toList(); } } @freezed class GridEvent with _$GridEvent { const factory GridEvent.initial() = InitialGrid; - const factory GridEvent.rename(String gridId, String name) = _Rename; const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; - const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.didReceiveRowUpdate(List rows) = _DidReceiveRowUpdate; + const factory GridEvent.didReceiveRowUpdate(List rows) = _DidReceiveRowUpdate; const factory GridEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @@ -142,7 +165,7 @@ class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, required List fields, - required List rows, + required List rows, required Option grid, }) = _GridState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index f87d9f8574..643a2c649e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -65,21 +65,12 @@ class RowData with _$RowData { required double height, }) = _RowData; - factory RowData.fromBlockRow(GridBlockRow row, List fields) { + factory RowData.fromBlockRow(String gridId, RowOrder row, List fields) { return RowData( - gridId: row.gridId, + gridId: gridId, rowId: row.rowId, fields: fields, - height: row.height, + height: row.height.toDouble(), ); } } - -@freezed -class GridBlockRow with _$GridBlockRow { - const factory GridBlockRow({ - required String gridId, - required String rowId, - required double height, - }) = _GridBlockRow; -} 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 6ff3852de5..8ca787f65c 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 @@ -73,7 +73,7 @@ class FlowyGrid extends StatefulWidget { class _FlowyGridState extends State { final _scrollController = GridScrollController(); - final _key = GlobalKey(); + // final _key = GlobalKey(); @override void dispose() { @@ -105,7 +105,7 @@ class _FlowyGridState extends State { slivers: [ _renderToolbar(gridId), GridHeader(gridId: gridId, fields: List.from(state.fields)), - _renderRows(context), + _renderRows(gridId: gridId, context: context), const GridFooter(), ], ), @@ -147,7 +147,7 @@ class _FlowyGridState extends State { ); } - Widget _renderRows(BuildContext context) { + Widget _renderRows({required String gridId, required BuildContext context}) { return BlocBuilder( buildWhen: (previous, current) { final rowChanged = previous.rows.length != current.rows.length; @@ -160,7 +160,7 @@ class _FlowyGridState extends State { (context, index) { final blockRow = context.read().state.rows[index]; final fields = context.read().state.fields; - final rowData = RowData.fromBlockRow(blockRow, fields); + final rowData = RowData.fromBlockRow(gridId, blockRow, fields); return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)); }, childCount: context.read().state.rows.length, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart index f1ff46af08..458e934756 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart @@ -84,10 +84,16 @@ class _RowActionCell extends StatelessWidget { return SizedBox( height: GridSize.typeOptionItemHeight, child: FlowyButton( - text: FlowyText.medium(action.title(), fontSize: 12), + text: FlowyText.medium( + action.title(), + fontSize: 12, + color: action.enable() ? theme.textColor : theme.shader3, + ), hoverColor: theme.hover, onTap: () { - action.performAction(context); + if (action.enable()) { + action.performAction(context); + } onDismissed(); }, leftIcon: svgWidget(action.iconName(), color: theme.iconColor), @@ -120,13 +126,22 @@ extension _RowActionExtension on _RowAction { } } + bool enable() { + switch (this) { + case _RowAction.duplicate: + return false; + case _RowAction.delete: + return true; + } + } + void performAction(BuildContext context) { switch (this) { case _RowAction.duplicate: - // context.read().add(const RowActionSheetEvent.duplicateRow()); + context.read().add(const RowActionSheetEvent.duplicateRow()); break; case _RowAction.delete: - // context.read().add(const RowActionSheetEvent.deleteRow()); + context.read().add(const RowActionSheetEvent.deleteRow()); break; } } 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 f613504047..e0fdcc33a5 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 @@ -858,7 +858,7 @@ class GridBlockOrder extends $pb.GeneratedMessage { class GridBlockOrderChangeset extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrderChangeset', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: IndexRowOrder.create) ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false @@ -867,7 +867,7 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage { GridBlockOrderChangeset._() : super(); factory GridBlockOrderChangeset({ $core.String? blockId, - $core.Iterable? insertedRows, + $core.Iterable? insertedRows, $core.Iterable? deletedRows, $core.Iterable? updatedRows, }) { @@ -917,7 +917,7 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List get insertedRows => $_getList(1); + $core.List get insertedRows => $_getList(1); @$pb.TagNumber(3) $core.List get deletedRows => $_getList(2); @@ -926,6 +926,82 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage { $core.List get updatedRows => $_getList(3); } +enum IndexRowOrder_OneOfIndex { + index_, + notSet +} + +class IndexRowOrder extends $pb.GeneratedMessage { + static const $core.Map<$core.int, IndexRowOrder_OneOfIndex> _IndexRowOrder_OneOfIndexByTag = { + 2 : IndexRowOrder_OneOfIndex.index_, + 0 : IndexRowOrder_OneOfIndex.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'IndexRowOrder', createEmptyInstance: create) + ..oo(0, [2]) + ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrder', subBuilder: RowOrder.create) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'index', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + IndexRowOrder._() : super(); + factory IndexRowOrder({ + RowOrder? rowOrder, + $core.int? index, + }) { + final _result = create(); + if (rowOrder != null) { + _result.rowOrder = rowOrder; + } + if (index != null) { + _result.index = index; + } + return _result; + } + factory IndexRowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory IndexRowOrder.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') + IndexRowOrder clone() => IndexRowOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + IndexRowOrder copyWith(void Function(IndexRowOrder) updates) => super.copyWith((message) => updates(message as IndexRowOrder)) as IndexRowOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static IndexRowOrder create() => IndexRowOrder._(); + IndexRowOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static IndexRowOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static IndexRowOrder? _defaultInstance; + + IndexRowOrder_OneOfIndex whichOneOfIndex() => _IndexRowOrder_OneOfIndexByTag[$_whichOneof(0)]!; + void clearOneOfIndex() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + RowOrder get rowOrder => $_getN(0); + @$pb.TagNumber(1) + set rowOrder(RowOrder v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasRowOrder() => $_has(0); + @$pb.TagNumber(1) + void clearRowOrder() => clearField(1); + @$pb.TagNumber(1) + RowOrder ensureRowOrder() => $_ensure(0); + + @$pb.TagNumber(2) + $core.int get index => $_getIZ(1); + @$pb.TagNumber(2) + set index($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasIndex() => $_has(1); + @$pb.TagNumber(2) + void clearIndex() => clearField(2); +} + class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') 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 0c1abf778e..0a565b2b49 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 @@ -176,14 +176,28 @@ const GridBlockOrderChangeset$json = const { '1': 'GridBlockOrderChangeset', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'insertedRows'}, + const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.IndexRowOrder', '10': 'insertedRows'}, const {'1': 'deleted_rows', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'deletedRows'}, const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.RowOrder', '10': 'updatedRows'}, ], }; /// Descriptor for `GridBlockOrderChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockOrderChangesetDescriptor = $convert.base64Decode('ChdHcmlkQmxvY2tPcmRlckNoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIuCg1pbnNlcnRlZF9yb3dzGAIgAygLMgkuUm93T3JkZXJSDGluc2VydGVkUm93cxIsCgxkZWxldGVkX3Jvd3MYAyADKAsyCS5Sb3dPcmRlclILZGVsZXRlZFJvd3MSLAoMdXBkYXRlZF9yb3dzGAQgAygLMgkuUm93T3JkZXJSC3VwZGF0ZWRSb3dz'); +final $typed_data.Uint8List gridBlockOrderChangesetDescriptor = $convert.base64Decode('ChdHcmlkQmxvY2tPcmRlckNoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M='); +@$core.Deprecated('Use indexRowOrderDescriptor instead') +const IndexRowOrder$json = const { + '1': 'IndexRowOrder', + '2': const [ + const {'1': 'row_order', '3': 1, '4': 1, '5': 11, '6': '.RowOrder', '10': 'rowOrder'}, + const {'1': 'index', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'index'}, + ], + '8': const [ + const {'1': 'one_of_index'}, + ], +}; + +/// Descriptor for `IndexRowOrder`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List indexRowOrderDescriptor = $convert.base64Decode('Cg1JbmRleFJvd09yZGVyEiYKCXJvd19vcmRlchgBIAEoCzIJLlJvd09yZGVyUghyb3dPcmRlchIWCgVpbmRleBgCIAEoBUgAUgVpbmRleEIOCgxvbmVfb2ZfaW5kZXg='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 1f8e2e2006..652617146b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -42,17 +42,30 @@ impl ClientGridBlockMetaEditor { }) } - pub(crate) async fn create_row(&self, row: RowMeta, start_row_id: Option) -> FlowyResult { + /// return current number of rows and the inserted index. The inserted index will be None if the start_row_id is None + pub(crate) async fn create_row( + &self, + row: RowMeta, + start_row_id: Option, + ) -> FlowyResult<(i32, Option)> { let mut row_count = 0; + let mut row_index = None; let _ = self .modify(|pad| { + if let Some(start_row_id) = start_row_id.as_ref() { + match pad.index_of_row(start_row_id) { + None => {} + Some(index) => row_index = Some(index + 1), + } + } + let change = pad.add_row_meta(row, start_row_id)?; row_count = pad.number_of_rows(); Ok(change) }) .await?; - Ok(row_count) + Ok((row_count, row_index)) } pub async fn delete_rows(&self, ids: Vec>) -> FlowyResult { @@ -89,7 +102,10 @@ impl ClientGridBlockMetaEditor { Ok(cell_metas) } - pub async fn get_row_orders(&self, row_ids: Option>>) -> FlowyResult> { + pub async fn get_row_orders(&self, row_ids: Option>>) -> FlowyResult> + where + T: AsRef + ToOwned + ?Sized, + { let row_orders = self .pad .read() diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 1fcddbd4da..0c4d1a2efd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -9,7 +9,7 @@ use dashmap::DashMap; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, - GridBlockOrder, GridBlockOrderChangeset, RowMeta, RowMetaChangeset, RowOrder, + GridBlockOrderChangeset, IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{RevisionManager, RevisionPersistence}; @@ -70,11 +70,13 @@ impl GridBlockMetaEditorManager { ) -> FlowyResult { let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?; let editor = self.get_editor(&row_meta.block_id).await?; - let row_order = RowOrder::from(&row_meta); - let row_count = editor.create_row(row_meta, start_row_id).await?; + + let mut index_row_order = IndexRowOrder::from(&row_meta); + let (row_count, row_index) = editor.create_row(row_meta, start_row_id).await?; + index_row_order.index = row_index; let _ = self - .notify_block_did_update_row(GridBlockOrderChangeset::from_update(block_id, vec![row_order])) + .notify_did_update_grid_rows(GridBlockOrderChangeset::from_insert(block_id, vec![index_row_order])) .await?; Ok(row_count) } @@ -90,12 +92,13 @@ impl GridBlockMetaEditorManager { let mut row_count = 0; for row in row_metas { let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; - inserted_row_orders.push(RowOrder::from(&row)); - row_count = editor.create_row(row, None).await?; + inserted_row_orders.push(IndexRowOrder::from(&row)); + row_count = editor.create_row(row, None).await?.0; } changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); + let _ = self - .notify_block_did_update_row(GridBlockOrderChangeset::from_insert(&block_id, inserted_row_orders)) + .notify_did_update_grid_rows(GridBlockOrderChangeset::from_insert(&block_id, inserted_row_orders)) .await?; } @@ -114,13 +117,26 @@ impl GridBlockMetaEditorManager { None => {} Some(row_order) => { let block_order_changeset = GridBlockOrderChangeset::from_update(&editor.block_id, vec![row_order]); - let _ = self.notify_block_did_update_row(block_order_changeset).await?; + let _ = self.notify_did_update_grid_rows(block_order_changeset).await?; } } Ok(()) } + pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> { + let row_id = row_id.to_owned(); + let block_id = self.persistence.get_block_id(&row_id)?; + let editor = self.get_editor(&block_id).await?; + let row_orders = editor.get_row_orders(Some(vec![Cow::Borrowed(&row_id)])).await?; + let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?; + let _ = self + .notify_did_update_grid_rows(GridBlockOrderChangeset::from_delete(&block_id, row_orders)) + .await?; + + Ok(()) + } + pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { let mut changesets = vec![]; for block_order in group_row_orders(row_orders) { @@ -167,7 +183,7 @@ impl GridBlockMetaEditorManager { pub async fn get_row_orders(&self, block_id: &str) -> FlowyResult> { let editor = self.get_editor(block_id).await?; - editor.get_row_orders(None).await + editor.get_row_orders::<&str>(None).await } pub(crate) async fn make_block_snapshots(&self, block_ids: Vec) -> FlowyResult> { @@ -197,7 +213,7 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn notify_block_did_update_row(&self, changeset: GridBlockOrderChangeset) -> FlowyResult<()> { + async fn notify_did_update_grid_rows(&self, changeset: GridBlockOrderChangeset) -> FlowyResult<()> { send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock) .payload(changeset) .send(); diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index bf63228287..f6029e360c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -70,7 +70,7 @@ impl CellDataOperation for DateTypeOption { ) -> Result { let changeset = changeset.into(); if changeset.parse::().is_err() || changeset.parse::().is_err() { - return Err(FlowyError::internal().context(format!("Parse {} failed", changeset.to_string()))); + return Err(FlowyError::internal().context(format!("Parse {} failed", changeset))); }; Ok(TypeOptionCellData::new(changeset, self.field_type()).json()) diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 30cd36b122..36ef357830 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -469,7 +469,7 @@ mod tests { let single_select = SingleSelectTypeOptionBuilder::default() .option(google_option.clone()) .option(facebook_option.clone()) - .option(twitter_option.clone()); + .option(twitter_option); let field_meta = FieldBuilder::new(single_select) .name("Platform") @@ -478,7 +478,7 @@ mod tests { let type_option = SingleSelectTypeOption::from(&field_meta); - let option_ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); + let option_ids = vec![google_option.id.clone(), facebook_option.id].join(SELECTION_IDS_SEPARATOR); let data = SelectOptionCellChangeset::from_insert(&option_ids).cell_data(); let cell_data = type_option.apply_changeset(data, None).unwrap(); assert_eq!(type_option.decode_cell_data(cell_data, &field_meta), google_option.name,); @@ -511,7 +511,7 @@ mod tests { let multi_select = MultiSelectTypeOptionBuilder::default() .option(google_option.clone()) .option(facebook_option.clone()) - .option(twitter_option.clone()); + .option(twitter_option); let field_meta = FieldBuilder::new(multi_select) .name("Platform") @@ -525,7 +525,7 @@ mod tests { let cell_data = type_option.apply_changeset(data, None).unwrap(); assert_eq!( type_option.decode_cell_data(cell_data, &field_meta), - vec![google_option.name.clone(), facebook_option.name.clone()].join(SELECTION_IDS_SEPARATOR), + vec![google_option.name.clone(), facebook_option.name].join(SELECTION_IDS_SEPARATOR), ); let data = SelectOptionCellChangeset::from_insert(&google_option.id).cell_data(); diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 44fc4c4e76..b94efcef99 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -268,11 +268,12 @@ impl ClientGridEditor { } } pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> { - todo!() + let _ = self.block_meta_manager.delete_row(row_id).await?; + Ok(()) } - pub async fn duplicate_row(&self, row_id: &str) -> FlowyResult<()> { - todo!() + pub async fn duplicate_row(&self, _row_id: &str) -> FlowyResult<()> { + Ok(()) } pub async fn get_cell(&self, params: &CellIdentifier) -> Option { @@ -429,7 +430,7 @@ impl ClientGridEditor { debug_assert!(field_metas.len() == 1); if let Some(field_meta) = field_metas.pop() { - send_dart_notification(&field_id, GridNotification::DidUpdateField) + send_dart_notification(field_id, GridNotification::DidUpdateField) .payload(field_meta) .send(); } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 26e889f1af..491b87b4c9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -4,7 +4,7 @@ use flowy_grid_data_model::entities::{ Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; -use std::borrow::Cow; + use std::collections::HashMap; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index f031c00743..29396a7c4b 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,7 +4,7 @@ use chrono::NaiveDateTime; use flowy_grid::services::field::{ MultiSelectTypeOption, SelectOption, SelectOptionCellChangeset, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, }; -use flowy_grid::services::row::{apply_cell_data_changeset, decode_cell_data, CellDataOperation, CreateRowMetaBuilder}; +use flowy_grid::services::row::{decode_cell_data, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, TypeOptionDataEntry, 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 9f09e4e975..d517b7f230 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -280,7 +280,7 @@ pub struct GridBlockOrderChangeset { pub block_id: String, #[pb(index = 2)] - pub inserted_rows: Vec, + pub inserted_rows: Vec, #[pb(index = 3)] pub deleted_rows: Vec, @@ -289,8 +289,30 @@ pub struct GridBlockOrderChangeset { pub updated_rows: Vec, } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct IndexRowOrder { + #[pb(index = 1)] + pub row_order: RowOrder, + + #[pb(index = 2, one_of)] + pub index: Option, +} + +impl std::convert::From for IndexRowOrder { + fn from(row_order: RowOrder) -> Self { + Self { row_order, index: None } + } +} + +impl std::convert::From<&RowMeta> for IndexRowOrder { + fn from(row: &RowMeta) -> Self { + let row_order = RowOrder::from(row); + Self::from(row_order) + } +} + impl GridBlockOrderChangeset { - pub fn from_insert(block_id: &str, inserted_rows: Vec) -> Self { + pub fn from_insert(block_id: &str, inserted_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows, 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 44c51f4a21..3d86c28702 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 @@ -2923,7 +2923,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { pub struct GridBlockOrderChangeset { // message fields pub block_id: ::std::string::String, - pub inserted_rows: ::protobuf::RepeatedField, + pub inserted_rows: ::protobuf::RepeatedField, pub deleted_rows: ::protobuf::RepeatedField, pub updated_rows: ::protobuf::RepeatedField, // special fields @@ -2968,10 +2968,10 @@ impl GridBlockOrderChangeset { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .RowOrder inserted_rows = 2; + // repeated .IndexRowOrder inserted_rows = 2; - pub fn get_inserted_rows(&self) -> &[RowOrder] { + pub fn get_inserted_rows(&self) -> &[IndexRowOrder] { &self.inserted_rows } pub fn clear_inserted_rows(&mut self) { @@ -2979,17 +2979,17 @@ impl GridBlockOrderChangeset { } // Param is passed by value, moved - pub fn set_inserted_rows(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_inserted_rows(&mut self, v: ::protobuf::RepeatedField) { self.inserted_rows = v; } // Mutable pointer to the field. - pub fn mut_inserted_rows(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_inserted_rows(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.inserted_rows } // Take field - pub fn take_inserted_rows(&mut self) -> ::protobuf::RepeatedField { + pub fn take_inserted_rows(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.inserted_rows, ::protobuf::RepeatedField::new()) } @@ -3174,7 +3174,7 @@ impl ::protobuf::Message for GridBlockOrderChangeset { |m: &GridBlockOrderChangeset| { &m.block_id }, |m: &mut GridBlockOrderChangeset| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "inserted_rows", |m: &GridBlockOrderChangeset| { &m.inserted_rows }, |m: &mut GridBlockOrderChangeset| { &mut m.inserted_rows }, @@ -3225,6 +3225,238 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrderChangeset { } } +#[derive(PartialEq,Clone,Default)] +pub struct IndexRowOrder { + // message fields + pub row_order: ::protobuf::SingularPtrField, + // message oneof groups + pub one_of_index: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a IndexRowOrder { + fn default() -> &'a IndexRowOrder { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum IndexRowOrder_oneof_one_of_index { + index(i32), +} + +impl IndexRowOrder { + pub fn new() -> IndexRowOrder { + ::std::default::Default::default() + } + + // .RowOrder row_order = 1; + + + pub fn get_row_order(&self) -> &RowOrder { + self.row_order.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_row_order(&mut self) { + self.row_order.clear(); + } + + pub fn has_row_order(&self) -> bool { + self.row_order.is_some() + } + + // Param is passed by value, moved + pub fn set_row_order(&mut self, v: RowOrder) { + self.row_order = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_order(&mut self) -> &mut RowOrder { + if self.row_order.is_none() { + self.row_order.set_default(); + } + self.row_order.as_mut().unwrap() + } + + // Take field + pub fn take_row_order(&mut self) -> RowOrder { + self.row_order.take().unwrap_or_else(|| RowOrder::new()) + } + + // int32 index = 2; + + + pub fn get_index(&self) -> i32 { + match self.one_of_index { + ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) => v, + _ => 0, + } + } + pub fn clear_index(&mut self) { + self.one_of_index = ::std::option::Option::None; + } + + pub fn has_index(&self) -> bool { + match self.one_of_index { + ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_index(&mut self, v: i32) { + self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) + } +} + +impl ::protobuf::Message for IndexRowOrder { + fn is_initialized(&self) -> bool { + for v in &self.row_order { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_order)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(is.read_int32()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.row_order.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let ::std::option::Option::Some(ref v) = self.one_of_index { + match v { + &IndexRowOrder_oneof_one_of_index::index(v) => { + my_size += ::protobuf::rt::value_size(2, v, ::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 let Some(ref v) = self.row_order.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_index { + match v { + &IndexRowOrder_oneof_one_of_index::index(v) => { + os.write_int32(2, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> IndexRowOrder { + IndexRowOrder::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_order", + |m: &IndexRowOrder| { &m.row_order }, + |m: &mut IndexRowOrder| { &mut m.row_order }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "index", + IndexRowOrder::has_index, + IndexRowOrder::get_index, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "IndexRowOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static IndexRowOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(IndexRowOrder::new) + } +} + +impl ::protobuf::Clear for IndexRowOrder { + fn clear(&mut self) { + self.row_order.clear(); + self.one_of_index = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for IndexRowOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for IndexRowOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GridBlock { // message fields @@ -5640,34 +5872,36 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\ \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\ - \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc0\x01\n\x17GridBlockOr\ - derChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12.\n\ - \rinserted_rows\x18\x02\x20\x03(\x0b2\t.RowOrderR\x0cinsertedRows\x12,\n\ - \x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\ - \x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"E\n\t\ - GridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\ - \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08\ - field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\ - \x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07gri\ - d_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01\ - (\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\ - \n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\ - \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ - \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ - R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ - lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ - \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ - idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ - \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ - rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ - \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ - \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ - \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ - ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ - ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ - \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ - ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ - \x0bblockOrdersb\x06proto3\ + \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc5\x01\n\x17GridBlockOr\ + derChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\ + \rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\ + \x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\ + \x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\ + \"_\n\rIndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\ + \x08rowOrder\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\ + \x0cone_of_index\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ + id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\ + \x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\ + \x07content\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificati\ + onData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08f\ + ield_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\ + \x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07content\ + B\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\ + \x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\ + \n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05va\ + lue\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ + \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ + _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\ + \x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12Cre\ + ateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type\ + _option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_fie\ + ld_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_fiel\ + d_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFiel\ + dOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_\ + id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\ + \x0b2\x0f.GridBlockOrderR\x0bblockOrdersb\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 8c1b48e7a4..cad2a6a108 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 @@ -61,10 +61,14 @@ message GridBlockOrder { } message GridBlockOrderChangeset { string block_id = 1; - repeated RowOrder inserted_rows = 2; + repeated IndexRowOrder inserted_rows = 2; repeated RowOrder deleted_rows = 3; repeated RowOrder updated_rows = 4; } +message IndexRowOrder { + RowOrder row_order = 1; + oneof one_of_index { int32 index = 2; }; +} message GridBlock { string id = 1; repeated RowOrder row_orders = 2; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index f416b55141..97c3ed963a 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -48,14 +48,11 @@ impl GridBlockMetaPad { ) -> CollaborateResult> { self.modify(|rows| { if let Some(start_row_id) = start_row_id { - if start_row_id.is_empty() { - rows.insert(0, Arc::new(row)); - return Ok(Some(())); - } - - if let Some(index) = rows.iter().position(|row| row.id == start_row_id) { - rows.insert(index + 1, Arc::new(row)); - return Ok(Some(())); + if !start_row_id.is_empty() { + if let Some(index) = rows.iter().position(|row| row.id == start_row_id) { + rows.insert(index + 1, Arc::new(row)); + return Ok(Some(())); + } } } @@ -121,6 +118,13 @@ impl GridBlockMetaPad { self.rows.len() as i32 } + pub fn index_of_row(&self, row_id: &str) -> Option { + self.rows + .iter() + .position(|row| row.id == row_id) + .map(|index| index as i32) + } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { From fbb2f49b6f3f78f8da07022a58121e175dce0dd1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 14:33:34 +0800 Subject: [PATCH 127/179] chore: enable rust lint and test by remove path --- .github/workflows/rust_lint.yml | 6 ------ .github/workflows/rust_test.yml | 6 ------ .../flowy-grid-data-model/tests/serde_test.rs | 20 +------------------ .../src/client_grid/grid_block_meta_pad.rs | 10 +++++----- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/.github/workflows/rust_lint.yml b/.github/workflows/rust_lint.yml index 9b39f28f2d..ac650b197b 100644 --- a/.github/workflows/rust_lint.yml +++ b/.github/workflows/rust_lint.yml @@ -3,14 +3,8 @@ name: Rust lint on: push: branches: [ main ] - paths: - - 'frontend/rust-lib' - - 'shared-lib' pull_request: branches: [ main ] - paths: - - 'frontend/rust-lib' - - 'shared-lib' env: diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml index e58db025b4..84617fb2c2 100644 --- a/.github/workflows/rust_test.yml +++ b/.github/workflows/rust_test.yml @@ -4,15 +4,9 @@ on: push: branches: - 'main' - paths: - - 'frontend/rust-lib' - - 'shared-lib' pull_request: branches: - 'main' - paths: - - 'frontend/rust-lib' - - 'shared-lib' env: CARGO_TERM_COLOR: always diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 0847950b98..2bae3f6a79 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -1,23 +1,5 @@ use flowy_grid_data_model::entities::*; -#[test] -fn grid_serde_test() { - let grid_id = "1".to_owned(); - let fields = vec![create_field("1")]; - let grid = GridMeta { - grid_id, - fields, - blocks: vec![], - }; - - let grid_1_json = serde_json::to_string(&grid).unwrap(); - let _: GridMeta = serde_json::from_str(&grid_1_json).unwrap(); - assert_eq!( - grid_1_json, - r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"blocks":[]}"# - ) -} - #[test] fn grid_default_serde_test() { let grid_id = "1".to_owned(); @@ -28,7 +10,7 @@ fn grid_default_serde_test() { }; let json = serde_json::to_string(&grid).unwrap(); - assert_eq!(json, r#"{"id":"1","fields":[],"blocks":[]}"#) + assert_eq!(json, r#"{"grid_id":"1","fields":[],"blocks":[]}"#) } fn create_field(field_id: &str) -> FieldMeta { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 97c3ed963a..39b38e2b84 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -309,8 +309,8 @@ mod tests { let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row_meta(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); - assert_eq!(*pad.rows[0], row_3); - assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[0], row_1); + assert_eq!(*pad.rows[1], row_3); assert_eq!(*pad.rows[2], row_2); } @@ -325,9 +325,9 @@ mod tests { let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row_meta(row_3.clone(), Some("".to_string())).unwrap().unwrap(); - assert_eq!(*pad.rows[0], row_3); - assert_eq!(*pad.rows[1], row_1); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.rows[0], row_1); + assert_eq!(*pad.rows[1], row_2); + assert_eq!(*pad.rows[2], row_3); } #[test] From df6871e777833185ca3b1bb4bb7649d91d552e59 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 14:40:57 +0800 Subject: [PATCH 128/179] chore: fix wanrings --- .github/workflows/dart_lint.yml | 4 ---- frontend/app_flowy/lib/startup/deps_resolver.dart | 1 - .../app_flowy/lib/workspace/application/grid/grid_bloc.dart | 1 - .../presentation/plugins/grid/src/widgets/row/grid_row.dart | 1 - .../rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs | 1 + frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs | 1 + 6 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dart_lint.yml b/.github/workflows/dart_lint.yml index 2b4a995cce..69cf8e46c7 100644 --- a/.github/workflows/dart_lint.yml +++ b/.github/workflows/dart_lint.yml @@ -8,12 +8,8 @@ name: Flutter lint on: push: branches: [ main ] - paths: - - 'frontend/app_flowy' pull_request: branches: [ main ] - paths: - - 'frontend/app_flowy' env: CARGO_TERM_COLOR: always diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 98ab00d0e4..abf6fffd21 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -5,7 +5,6 @@ import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/row/row_listener.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.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 index bf56b9d864..ddb1d41ca3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index a5b6a405a6..baeed922d7 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -5,7 +5,6 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/p import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; diff --git a/frontend/rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs b/frontend/rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs index e69de29bb2..8b13789179 100644 --- a/frontend/rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs +++ b/frontend/rust-lib/flowy-revision/src/cache/disk/folder_rev_impl.rs @@ -0,0 +1 @@ + diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs index e69de29bb2..8b13789179 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs @@ -0,0 +1 @@ + From 5db5fd118e5e353bbf4c6ddad5ef5fecfd8c5fb8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 15:07:06 +0800 Subject: [PATCH 129/179] chore: highlight cell when edit --- .../grid/src/widgets/cell/date_cell.dart | 17 ++++++++++++----- .../grid/src/widgets/cell/number_cell.dart | 2 +- .../cell/selection_cell/selection_cell.dart | 16 +++++++++++++--- .../cell/selection_cell/selection_editor.dart | 7 +++++++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index 70febd9adf..24351a425a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/widgets.dart'; @@ -7,7 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:window_size/window_size.dart'; -class DateCell extends StatefulWidget { +class DateCell extends GridCell { final CellData cellData; const DateCell({ @@ -37,10 +38,16 @@ class _DateCellState extends State { return SizedBox.expand( child: GestureDetector( behavior: HitTestBehavior.opaque, - onTap: () => _CellCalendar.show( - context, - onSelected: (day) => context.read().add(DateCellEvent.selectDay(day)), - ), + onTap: () { + widget.setFocus(context, true); + _CellCalendar.show( + context, + onSelected: (day) { + widget.setFocus(context, false); + context.read().add(DateCellEvent.selectDay(day)); + }, + ); + }, child: MouseRegion( opaque: false, cursor: SystemMouseCursors.click, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index ba9d75ed1b..fc31340c9f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -6,7 +6,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/c import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class NumberCell extends StatefulWidget { +class NumberCell extends GridCell { final CellData cellData; const NumberCell({ diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index ac0f7d391b..a7cf70a64e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -1,12 +1,13 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'extension.dart'; import 'selection_editor.dart'; -class SingleSelectCell extends StatefulWidget { +class SingleSelectCell extends GridCell { final CellData cellData; const SingleSelectCell({ @@ -37,7 +38,14 @@ class _SingleSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - SelectOptionCellEditor.show(context, state.cellData, state.options, state.selectedOptions); + widget.setFocus(context, true); + SelectOptionCellEditor.show( + context, + state.cellData, + state.options, + state.selectedOptions, + () => widget.setFocus(context, false), + ); }, child: Row(children: children), ), @@ -55,7 +63,7 @@ class _SingleSelectCellState extends State { } //---------------------------------------------------------------- -class MultiSelectCell extends StatefulWidget { +class MultiSelectCell extends GridCell { final CellData cellData; const MultiSelectCell({ @@ -86,11 +94,13 @@ class _MultiSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { + widget.setFocus(context, true); SelectOptionCellEditor.show( context, state.cellData, state.options, state.selectedOptions, + () => widget.setFocus(context, false), ); }, child: Row(children: children), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index ebaabbfb0b..feefb552cd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -28,11 +28,13 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { final CellData cellData; final List options; final List selectedOptions; + final VoidCallback onDismissed; const SelectOptionCellEditor({ required this.cellData, required this.options, required this.selectedOptions, + required this.onDismissed, Key? key, }) : super(key: key); @@ -67,12 +69,14 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { CellData cellData, List options, List selectedOptions, + VoidCallback onDismissed, ) { SelectOptionCellEditor.remove(context); final editor = SelectOptionCellEditor( cellData: cellData, options: options, selectedOptions: selectedOptions, + onDismissed: onDismissed, ); // @@ -98,6 +102,9 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { @override bool asBarrier() => true; + + @override + void didRemove() => onDismissed(); } class _OptionList extends StatelessWidget { From 43095cb0ddb3ccc2639ab762684644f137fb50e6 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 16:29:45 +0800 Subject: [PATCH 130/179] chore: close grid handler --- .../workspace/application/doc/doc_bloc.dart | 2 +- .../workspace/application/grid/grid_bloc.dart | 18 ++++++++++-------- .../application/grid/grid_service.dart | 18 ++++++++++++++---- .../plugins/grid/src/grid_page.dart | 8 +++----- .../src/services/view/controller.rs | 2 +- frontend/rust-lib/flowy-grid/src/manager.rs | 2 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 2 +- .../rust-lib/flowy-text-block/src/manager.rs | 1 + .../src/client_grid/grid_block_meta_pad.rs | 6 +++++- .../src/server_document/document_manager.rs | 2 +- 10 files changed, 38 insertions(+), 23 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 1f746ffec0..8d944c34ac 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart @@ -65,7 +65,7 @@ class DocumentBloc extends Bloc { await _subscription?.cancel(); } - service.closeDocument(docId: view.id); + await service.closeDocument(docId: view.id); return super.close(); } 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 ddb1d41ca3..02a30baa5d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -13,16 +13,15 @@ import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { - final View view; final GridService _gridService; final GridListener _gridListener; final GridFieldsListener _fieldListener; - GridBloc({required this.view}) + GridBloc({required View view}) : _fieldListener = GridFieldsListener(gridId: view.id), - _gridService = GridService(), + _gridService = GridService(gridId: view.id), _gridListener = GridListener(gridId: view.id), - super(GridState.initial()) { + super(GridState.initial(view.id)) { on( (event, emit) async { await event.map( @@ -31,7 +30,7 @@ class GridBloc extends Bloc { _startListening(); }, createRow: (_CreateRow value) { - _gridService.createRow(gridId: view.id); + _gridService.createRow(); }, updateDesc: (_Desc value) {}, didReceiveRowUpdate: (_DidReceiveRowUpdate value) { @@ -47,6 +46,7 @@ class GridBloc extends Bloc { @override Future close() async { + await _gridService.closeGrid(); await _fieldListener.stop(); await _gridListener.stop(); return super.close(); @@ -86,7 +86,7 @@ class GridBloc extends Bloc { } Future _loadGrid(Emitter emit) async { - final result = await _gridService.loadGrid(gridId: view.id); + final result = await _gridService.loadGrid(); return Future( () => result.fold( (grid) async => await _loadFields(grid, emit), @@ -96,7 +96,7 @@ class GridBloc extends Bloc { } Future _loadFields(Grid grid, Emitter emit) async { - final result = await _gridService.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); + final result = await _gridService.getFields(fieldOrders: grid.fieldOrders); return Future( () => result.fold( (fields) { @@ -162,17 +162,19 @@ class GridEvent with _$GridEvent { @freezed class GridState with _$GridState { const factory GridState({ + required String gridId, required GridLoadingState loadingState, required List fields, required List rows, required Option grid, }) = _GridState; - factory GridState.initial() => GridState( + factory GridState.initial(String gridId) => GridState( loadingState: const _Loading(), fields: [], rows: [], grid: none(), + gridId: gridId, ); } 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 bf558cb574..a150b234d0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -1,27 +1,37 @@ +import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-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> loadGrid({required String gridId}) async { + final String gridId; + GridService({ + required this.gridId, + }); + + Future> loadGrid() async { await FolderEventSetLatestView(ViewId(value: gridId)).send(); final payload = GridId(value: gridId); return GridEventGetGridData(payload).send(); } - Future> createRow({required String gridId, Option? startRowId}) { + Future> createRow({Option? startRowId}) { CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; startRowId?.fold(() => null, (id) => payload.startRowId = id); return GridEventCreateRow(payload).send(); } - Future> getFields({required String gridId, required List fieldOrders}) { + Future> getFields({required List fieldOrders}) { final payload = QueryFieldPayload.create() ..gridId = gridId ..fieldOrders = RepeatedFieldOrder(items: fieldOrders); return GridEventGetFields(payload).send(); } + + Future> closeGrid() { + final request = ViewId(value: gridId); + return FolderEventCloseView(request).send(); + } } 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 8ca787f65c..657701a916 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 @@ -83,8 +83,6 @@ class _FlowyGridState extends State { @override Widget build(BuildContext context) { - final gridId = context.read().view.id; - return BlocBuilder( buildWhen: (previous, current) => previous.fields != current.fields, builder: (context, state) { @@ -103,9 +101,9 @@ class _FlowyGridState extends State { physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ - _renderToolbar(gridId), - GridHeader(gridId: gridId, fields: List.from(state.fields)), - _renderRows(gridId: gridId, context: context), + _renderToolbar(state.gridId), + GridHeader(gridId: state.gridId, fields: List.from(state.fields)), + _renderRows(gridId: state.gridId, context: context), const GridFooter(), ], ), 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 185521eac3..695bfaf028 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -151,7 +151,7 @@ impl ViewController { } } let processor = self.get_data_processor_from_view_id(¶ms.value).await?; - let _ = processor.close_container(¶ms.value).await?; + let _ = processor.delete_container(¶ms.value).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 9f8d0c77e1..218dff8782 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -73,7 +73,7 @@ impl GridManager { self.get_or_create_grid_editor(grid_id).await } - #[tracing::instrument(level = "trace", skip_all, fields(grid_id), err)] + #[tracing::instrument(level = "debug", 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); diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 6c0be5c1c5..33c94f9f0f 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -67,7 +67,7 @@ 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_block={}", level)); + filters.push(format!("flowy_text_block={}", level)); filters.push(format!("flowy_grid={}", level)); filters.push(format!("flowy_collaboration={}", "debug")); filters.push(format!("dart_notify={}", level)); diff --git a/frontend/rust-lib/flowy-text-block/src/manager.rs b/frontend/rust-lib/flowy-text-block/src/manager.rs index a79f5cb3f4..8a34c6916d 100644 --- a/frontend/rust-lib/flowy-text-block/src/manager.rs +++ b/frontend/rust-lib/flowy-text-block/src/manager.rs @@ -118,6 +118,7 @@ impl TextBlockManager { } } + #[tracing::instrument(level = "trace", skip(self, pool), err)] async fn make_text_block_editor( &self, block_id: &str, diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 39b38e2b84..95d4aa4a72 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -163,7 +163,11 @@ impl GridBlockMetaPad { match cal_diff::(old, new) { None => Ok(None), Some(delta) => { - tracing::debug!("[GridBlockMeta] Composing change {}", delta.to_delta_str()); + tracing::debug!("[GridBlockMeta] Composing delta {}", delta.to_delta_str()); + tracing::debug!( + "[GridBlockMeta] Composing str {}", + delta.to_str().unwrap_or("".to_string()) + ); self.delta = self.delta.compose(&delta)?; Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } diff --git a/shared-lib/flowy-sync/src/server_document/document_manager.rs b/shared-lib/flowy-sync/src/server_document/document_manager.rs index 3232f0e9ca..8ce136480e 100644 --- a/shared-lib/flowy-sync/src/server_document/document_manager.rs +++ b/shared-lib/flowy-sync/src/server_document/document_manager.rs @@ -163,7 +163,6 @@ impl ServerDocumentManager { } } - #[tracing::instrument(level = "debug", skip(self, repeated_revision), err)] async fn create_document( &self, doc_id: &str, @@ -182,6 +181,7 @@ impl ServerDocumentManager { } } + #[tracing::instrument(level = "debug", skip(self, doc), err)] async fn create_document_handler(&self, doc: TextBlockInfo) -> Result, CollaborateError> { let persistence = self.persistence.clone(); let handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence)) From 9d629412c8ee4c9ec82963f8c302aac8f3bca80f Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Apr 2022 20:21:28 +0800 Subject: [PATCH 131/179] chore: fix transform field type error --- frontend/rust-lib/flowy-grid/src/macros.rs | 4 +- .../type_options/checkbox_type_option.rs | 5 +- .../field/type_options/date_type_option.rs | 5 +- .../field/type_options/number_type_option.rs | 5 +- .../type_options/selection_type_option.rs | 2 +- .../field/type_options/text_type_option.rs | 6 ++- .../src/services/row/cell_data_operation.rs | 46 +++++++++++++++---- .../flowy-grid/src/services/row/row_loader.rs | 22 ++------- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- .../src/entities/meta.rs | 10 ++-- .../src/client_grid/grid_block_meta_pad.rs | 4 +- 12 files changed, 71 insertions(+), 44 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index e635e63790..79e0e106eb 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -30,7 +30,7 @@ macro_rules! impl_type_option { ($target: ident, $field_type:expr) => { impl std::convert::From<&FieldMeta> for $target { fn from(field_meta: &FieldMeta) -> $target { - match field_meta.get_type_option_entry::<$target>(Some($field_type)) { + match field_meta.get_type_option_entry::<$target>(&$field_type) { None => $target::default(), Some(target) => target, } @@ -63,7 +63,7 @@ macro_rules! impl_type_option { } } - impl TypeOptionDataEntity for $target { + impl TypeOptionDataDeserializer for $target { fn from_json_str(s: &str) -> $target { match serde_json::from_str(s) { Ok(obj) => obj, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index b3e1eb37f9..994e82829a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -4,7 +4,10 @@ use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellD use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{ + CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, +}; + use serde::{Deserialize, Serialize}; use std::str::FromStr; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index f6029e360c..e6d1204d19 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -5,7 +5,10 @@ use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{ + CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, +}; + use serde::{Deserialize, Serialize}; use std::str::FromStr; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 7b03adfc74..6f3cec4341 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -2,7 +2,10 @@ use crate::impl_type_option; use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{ + CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, +}; + use lazy_static::lazy_static; use rust_decimal::Decimal; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 36ef357830..791ec15718 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -7,7 +7,7 @@ use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError}; use flowy_grid_data_model::entities::{ - CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry, + CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, }; use flowy_grid_data_model::parser::NotEmptyUuid; use serde::{Deserialize, Serialize}; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 46ce48db10..5984b2552a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -4,7 +4,9 @@ use crate::services::row::{decode_cell_data, CellDataChangeset, CellDataOperatio use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{ + CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, +}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -38,7 +40,7 @@ impl CellDataOperation for RichTextTypeOption { || type_option_cell_data.is_multi_select() || type_option_cell_data.is_number() { - decode_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned()) + decode_cell_data(data, &field_meta, &type_option_cell_data.field_type).unwrap_or_else(|| "".to_owned()) } else { type_option_cell_data.data } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index e34c25b488..7384173b60 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -106,17 +106,43 @@ pub fn apply_cell_data_changeset>( FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), } } +// +// #[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)] +// pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Result { +// let s = match field_meta.field_type { +// FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta), +// FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta), +// FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta), +// FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), +// FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), +// FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta), +// }; +// tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str()); +// Ok(s) +// } -#[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)] -pub fn decode_cell_data(data: String, field_meta: &FieldMeta) -> Result { - let s = match field_meta.field_type { - FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta), - FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta), - FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta), - FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), - FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), - FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta), +#[tracing::instrument(level = "trace", skip(field_meta, data), fields(content))] +pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Option { + let s = match field_type { + FieldType::RichText => field_meta + .get_type_option_entry::(field_type)? + .decode_cell_data(data, field_meta), + FieldType::Number => field_meta + .get_type_option_entry::(field_type)? + .decode_cell_data(data, field_meta), + FieldType::DateTime => field_meta + .get_type_option_entry::(field_type)? + .decode_cell_data(data, field_meta), + FieldType::SingleSelect => field_meta + .get_type_option_entry::(field_type)? + .decode_cell_data(data, field_meta), + FieldType::MultiSelect => field_meta + .get_type_option_entry::(field_type)? + .decode_cell_data(data, field_meta), + FieldType::Checkbox => field_meta + .get_type_option_entry::(field_type)? + .decode_cell_data(data, field_meta), }; tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str()); - Ok(s) + Some(s) } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 491b87b4c9..e9c75d4f16 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -34,28 +34,16 @@ pub fn make_cell_by_field_id( cell_meta: CellMeta, ) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; - match decode_cell_data(cell_meta.data, field_meta) { - Ok(content) => { - let cell = Cell::new(&field_id, content); - Some((field_id, cell)) - } - Err(e) => { - tracing::error!("{}", e); - None - } - } + let content = decode_cell_data(cell_meta.data, field_meta, &field_meta.field_type)?; + let cell = Cell::new(&field_id, content); + Some((field_id, cell)) } #[allow(dead_code)] pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { let cell_meta = row_meta.cells.get(field_id)?.clone(); - match decode_cell_data(cell_meta.data, field_meta) { - Ok(content) => Some(Cell::new(field_id, content)), - Err(e) => { - tracing::error!("{}", e); - None - } - } + let content = decode_cell_data(cell_meta.data, field_meta, &field_meta.field_type)?; + Some(Cell::new(field_id, content)) } pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 29396a7c4b..a9d7dacec8 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -287,7 +287,7 @@ async fn grid_row_add_date_cell_test() { let date_field = date_field.unwrap(); let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); assert_eq!( - decode_cell_data(cell_data.data.clone(), &date_field).unwrap(), + decode_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type).unwrap(), "2022/03/16 08:31", ); let scripts = vec![CreateRow { context }]; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 9c3cfd53d7..927c505b55 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -258,7 +258,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { let cloned_field_meta = field_meta.clone(); let type_option_data = field_meta - .get_type_option_entry::(None) + .get_type_option_entry::(&field_meta.field_type) .unwrap() .protobuf_bytes() .to_vec(); @@ -290,7 +290,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet let field_meta = FieldBuilder::new(single_select).name("Name").visibility(true).build(); let cloned_field_meta = field_meta.clone(); let type_option_data = field_meta - .get_type_option_entry::(None) + .get_type_option_entry::(&field_meta.field_type) .unwrap() .protobuf_bytes() .to_vec(); diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index b78b166802..09fa11c003 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -122,12 +122,14 @@ impl FieldMeta { } } - pub fn insert_type_option_entry(&mut self, entry: &T) { + pub fn insert_type_option_entry(&mut self, entry: &T) + where + T: TypeOptionDataEntry + ?Sized, + { self.type_options.insert(entry.field_type().type_id(), entry.json_str()); } - pub fn get_type_option_entry(&self, field_type: Option) -> Option { - let field_type = field_type.as_ref().unwrap_or(&self.field_type); + pub fn get_type_option_entry(&self, field_type: &FieldType) -> Option { self.type_options .get(&field_type.type_id()) .map(|s| T::from_json_str(s)) @@ -149,7 +151,7 @@ pub trait TypeOptionDataEntry { fn protobuf_bytes(&self) -> Bytes; } -pub trait TypeOptionDataEntity { +pub trait TypeOptionDataDeserializer { fn from_json_str(s: &str) -> Self; fn from_protobuf_bytes(bytes: Bytes) -> Self; } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 95d4aa4a72..7a06551525 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -165,8 +165,8 @@ impl GridBlockMetaPad { Some(delta) => { tracing::debug!("[GridBlockMeta] Composing delta {}", delta.to_delta_str()); tracing::debug!( - "[GridBlockMeta] Composing str {}", - delta.to_str().unwrap_or("".to_string()) + "[GridBlockMeta] current delta: {}", + self.delta.to_str().unwrap_or("".to_string()) ); self.delta = self.delta.compose(&delta)?; Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) From 2dd59305603dc150a7baf6fcf265c447e1bef818 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 14:09:50 +0800 Subject: [PATCH 132/179] fix: deserial cells data from delta error --- .../grid/cell_bloc/cell_service.dart | 5 +- .../application/grid/field/field_service.dart | 1 - .../grid/src/widgets/cell/cell_builder.dart | 2 +- .../src/widgets/header/field_switcher.dart | 1 - .../widgets/header/field_type_extension.dart | 3 +- .../src/widgets/header/field_type_list.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 2 +- .../flowy-grid-data-model/grid.pb.dart | 380 +- .../flowy-grid-data-model/grid.pbenum.dart | 27 + .../flowy-grid-data-model/grid.pbjson.dart | 58 + .../flowy-grid-data-model/meta.pb.dart | 1086 ----- .../flowy-grid-data-model/meta.pbenum.dart | 34 - .../flowy-grid-data-model/meta.pbjson.dart | 217 - .../flowy-grid-data-model/meta.pbserver.dart | 9 - .../flowy-grid-data-model/protobuf.dart | 1 - frontend/rust-lib/Cargo.lock | 7 +- frontend/rust-lib/flowy-grid/Cargo.toml | 1 + .../rust-lib/flowy-grid/src/event_handler.rs | 8 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 2 +- .../src/services/block_meta_manager.rs | 4 +- .../src/services/field/field_builder.rs | 4 +- .../type_options/selection_type_option.rs | 6 +- .../field/type_options/text_type_option.rs | 2 +- .../flowy-grid/src/services/grid_editor.rs | 6 +- .../src/services/row/row_builder.rs | 3 +- .../flowy-grid/src/services/row/row_loader.rs | 5 +- .../flowy-grid/tests/grid/grid_test.rs | 6 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 8 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 4 +- shared-lib/Cargo.lock | 18 + shared-lib/flowy-grid-data-model/Cargo.toml | 2 +- shared-lib/flowy-grid-data-model/Flowy.toml | 2 +- .../src/entities/grid.rs | 173 +- .../src/entities/meta.rs | 276 +- .../src/protobuf/model/grid.rs | 1249 +++++- .../src/protobuf/model/meta.rs | 3520 ----------------- .../src/protobuf/model/mod.rs | 3 - .../src/protobuf/proto/grid.proto | 26 +- .../src/protobuf/proto/meta.proto | 76 - .../src/client_grid/grid_block_meta_pad.rs | 7 +- 40 files changed, 1908 insertions(+), 5338 deletions(-) delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart delete mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart delete mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs delete mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index 9bdd48c259..dfce5d3993 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,8 +1,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; class CellService { @@ -14,7 +13,7 @@ class CellService { required String rowId, required String data, }) { - final payload = CellMetaChangeset.create() + final payload = CellChangeset.create() ..gridId = gridId ..fieldId = fieldId ..rowId = rowId diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 2336c4f340..bdf8c0d261 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -3,7 +3,6 @@ import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; class FieldService { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 3b84ac557a..2b00a13a10 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index decaaec611..80ebd456e7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -10,7 +10,6 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart index ce37afe861..a4da8fa1b9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart @@ -1,5 +1,4 @@ - -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart index 2965556f60..bfced8f421 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart @@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:flutter/material.dart'; import 'field_type_extension.dart'; import 'package:flutter_bloc/flutter_bloc.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 8544bc6edd..93a0abfee2 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 @@ -291,7 +291,7 @@ class GridEventGetCell { } class GridEventUpdateCell { - CellMetaChangeset request; + CellChangeset request; GridEventUpdateCell(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 e0fdcc33a5..2c3a848729 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -9,7 +9,9 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'meta.pbenum.dart' as $0; +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) @@ -79,7 +81,7 @@ class Field extends $pb.GeneratedMessage { ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e<$0.FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) @@ -91,7 +93,7 @@ class Field extends $pb.GeneratedMessage { $core.String? id, $core.String? name, $core.String? desc, - $0.FieldType? fieldType, + FieldType? fieldType, $core.bool? frozen, $core.bool? visibility, $core.int? width, @@ -169,9 +171,9 @@ class Field extends $pb.GeneratedMessage { void clearDesc() => clearField(3); @$pb.TagNumber(4) - $0.FieldType get fieldType => $_getN(3); + FieldType get fieldType => $_getN(3); @$pb.TagNumber(4) - set fieldType($0.FieldType v) { setField(4, v); } + set fieldType(FieldType v) { setField(4, v); } @$pb.TagNumber(4) $core.bool hasFieldType() => $_has(3); @$pb.TagNumber(4) @@ -266,7 +268,7 @@ class GetEditFieldContextPayload extends $pb.GeneratedMessage { ..oo(0, [2]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..e<$0.FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..e(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) ..hasRequiredFields = false ; @@ -274,7 +276,7 @@ class GetEditFieldContextPayload extends $pb.GeneratedMessage { factory GetEditFieldContextPayload({ $core.String? gridId, $core.String? fieldId, - $0.FieldType? fieldType, + FieldType? fieldType, }) { final _result = create(); if (gridId != null) { @@ -331,9 +333,9 @@ class GetEditFieldContextPayload extends $pb.GeneratedMessage { void clearFieldId() => clearField(2); @$pb.TagNumber(3) - $0.FieldType get fieldType => $_getN(2); + FieldType get fieldType => $_getN(2); @$pb.TagNumber(3) - set fieldType($0.FieldType v) { setField(3, v); } + set fieldType(FieldType v) { setField(3, v); } @$pb.TagNumber(3) $core.bool hasFieldType() => $_has(2); @$pb.TagNumber(3) @@ -344,7 +346,7 @@ class EditFieldPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'EditFieldPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..e<$0.FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..e(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) ..hasRequiredFields = false ; @@ -352,7 +354,7 @@ class EditFieldPayload extends $pb.GeneratedMessage { factory EditFieldPayload({ $core.String? gridId, $core.String? fieldId, - $0.FieldType? fieldType, + FieldType? fieldType, }) { final _result = create(); if (gridId != null) { @@ -406,9 +408,9 @@ class EditFieldPayload extends $pb.GeneratedMessage { void clearFieldId() => clearField(2); @$pb.TagNumber(3) - $0.FieldType get fieldType => $_getN(2); + FieldType get fieldType => $_getN(2); @$pb.TagNumber(3) - set fieldType($0.FieldType v) { setField(3, v); } + set fieldType(FieldType v) { setField(3, v); } @$pb.TagNumber(3) $core.bool hasFieldType() => $_has(2); @$pb.TagNumber(3) @@ -1698,3 +1700,355 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage { $core.List get blockOrders => $_getList(1); } +enum FieldChangesetPayload_OneOfName { + name, + notSet +} + +enum FieldChangesetPayload_OneOfDesc { + desc, + notSet +} + +enum FieldChangesetPayload_OneOfFieldType { + fieldType, + notSet +} + +enum FieldChangesetPayload_OneOfFrozen { + frozen, + notSet +} + +enum FieldChangesetPayload_OneOfVisibility { + visibility, + notSet +} + +enum FieldChangesetPayload_OneOfWidth { + width, + notSet +} + +enum FieldChangesetPayload_OneOfTypeOptionData { + typeOptionData, + notSet +} + +class FieldChangesetPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, FieldChangesetPayload_OneOfName> _FieldChangesetPayload_OneOfNameByTag = { + 3 : FieldChangesetPayload_OneOfName.name, + 0 : FieldChangesetPayload_OneOfName.notSet + }; + static const $core.Map<$core.int, FieldChangesetPayload_OneOfDesc> _FieldChangesetPayload_OneOfDescByTag = { + 4 : FieldChangesetPayload_OneOfDesc.desc, + 0 : FieldChangesetPayload_OneOfDesc.notSet + }; + static const $core.Map<$core.int, FieldChangesetPayload_OneOfFieldType> _FieldChangesetPayload_OneOfFieldTypeByTag = { + 5 : FieldChangesetPayload_OneOfFieldType.fieldType, + 0 : FieldChangesetPayload_OneOfFieldType.notSet + }; + static const $core.Map<$core.int, FieldChangesetPayload_OneOfFrozen> _FieldChangesetPayload_OneOfFrozenByTag = { + 6 : FieldChangesetPayload_OneOfFrozen.frozen, + 0 : FieldChangesetPayload_OneOfFrozen.notSet + }; + static const $core.Map<$core.int, FieldChangesetPayload_OneOfVisibility> _FieldChangesetPayload_OneOfVisibilityByTag = { + 7 : FieldChangesetPayload_OneOfVisibility.visibility, + 0 : FieldChangesetPayload_OneOfVisibility.notSet + }; + static const $core.Map<$core.int, FieldChangesetPayload_OneOfWidth> _FieldChangesetPayload_OneOfWidthByTag = { + 8 : FieldChangesetPayload_OneOfWidth.width, + 0 : FieldChangesetPayload_OneOfWidth.notSet + }; + static const $core.Map<$core.int, FieldChangesetPayload_OneOfTypeOptionData> _FieldChangesetPayload_OneOfTypeOptionDataByTag = { + 9 : FieldChangesetPayload_OneOfTypeOptionData.typeOptionData, + 0 : FieldChangesetPayload_OneOfTypeOptionData.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangesetPayload', createEmptyInstance: create) + ..oo(0, [3]) + ..oo(1, [4]) + ..oo(2, [5]) + ..oo(3, [6]) + ..oo(4, [7]) + ..oo(5, [8]) + ..oo(6, [9]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..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') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..a<$core.List<$core.int>>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + FieldChangesetPayload._() : super(); + factory FieldChangesetPayload({ + $core.String? fieldId, + $core.String? gridId, + $core.String? name, + $core.String? desc, + FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + $core.List<$core.int>? typeOptionData, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (gridId != null) { + _result.gridId = gridId; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + if (typeOptionData != null) { + _result.typeOptionData = typeOptionData; + } + return _result; + } + factory FieldChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldChangesetPayload.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') + FieldChangesetPayload clone() => FieldChangesetPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldChangesetPayload copyWith(void Function(FieldChangesetPayload) updates) => super.copyWith((message) => updates(message as FieldChangesetPayload)) as FieldChangesetPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldChangesetPayload create() => FieldChangesetPayload._(); + FieldChangesetPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldChangesetPayload? _defaultInstance; + + FieldChangesetPayload_OneOfName whichOneOfName() => _FieldChangesetPayload_OneOfNameByTag[$_whichOneof(0)]!; + void clearOneOfName() => clearField($_whichOneof(0)); + + FieldChangesetPayload_OneOfDesc whichOneOfDesc() => _FieldChangesetPayload_OneOfDescByTag[$_whichOneof(1)]!; + void clearOneOfDesc() => clearField($_whichOneof(1)); + + FieldChangesetPayload_OneOfFieldType whichOneOfFieldType() => _FieldChangesetPayload_OneOfFieldTypeByTag[$_whichOneof(2)]!; + void clearOneOfFieldType() => clearField($_whichOneof(2)); + + FieldChangesetPayload_OneOfFrozen whichOneOfFrozen() => _FieldChangesetPayload_OneOfFrozenByTag[$_whichOneof(3)]!; + void clearOneOfFrozen() => clearField($_whichOneof(3)); + + FieldChangesetPayload_OneOfVisibility whichOneOfVisibility() => _FieldChangesetPayload_OneOfVisibilityByTag[$_whichOneof(4)]!; + void clearOneOfVisibility() => clearField($_whichOneof(4)); + + FieldChangesetPayload_OneOfWidth whichOneOfWidth() => _FieldChangesetPayload_OneOfWidthByTag[$_whichOneof(5)]!; + void clearOneOfWidth() => clearField($_whichOneof(5)); + + FieldChangesetPayload_OneOfTypeOptionData whichOneOfTypeOptionData() => _FieldChangesetPayload_OneOfTypeOptionDataByTag[$_whichOneof(6)]!; + void clearOneOfTypeOptionData() => clearField($_whichOneof(6)); + + @$pb.TagNumber(1) + $core.String get fieldId => $_getSZ(0); + @$pb.TagNumber(1) + set fieldId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFieldId() => $_has(0); + @$pb.TagNumber(1) + void clearFieldId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get gridId => $_getSZ(1); + @$pb.TagNumber(2) + set gridId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasGridId() => $_has(1); + @$pb.TagNumber(2) + void clearGridId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get name => $_getSZ(2); + @$pb.TagNumber(3) + set name($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasName() => $_has(2); + @$pb.TagNumber(3) + void clearName() => clearField(3); + + @$pb.TagNumber(4) + $core.String get desc => $_getSZ(3); + @$pb.TagNumber(4) + set desc($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasDesc() => $_has(3); + @$pb.TagNumber(4) + void clearDesc() => clearField(4); + + @$pb.TagNumber(5) + FieldType get fieldType => $_getN(4); + @$pb.TagNumber(5) + set fieldType(FieldType v) { setField(5, v); } + @$pb.TagNumber(5) + $core.bool hasFieldType() => $_has(4); + @$pb.TagNumber(5) + void clearFieldType() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get frozen => $_getBF(5); + @$pb.TagNumber(6) + set frozen($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasFrozen() => $_has(5); + @$pb.TagNumber(6) + void clearFrozen() => clearField(6); + + @$pb.TagNumber(7) + $core.bool get visibility => $_getBF(6); + @$pb.TagNumber(7) + set visibility($core.bool v) { $_setBool(6, v); } + @$pb.TagNumber(7) + $core.bool hasVisibility() => $_has(6); + @$pb.TagNumber(7) + void clearVisibility() => clearField(7); + + @$pb.TagNumber(8) + $core.int get width => $_getIZ(7); + @$pb.TagNumber(8) + set width($core.int v) { $_setSignedInt32(7, v); } + @$pb.TagNumber(8) + $core.bool hasWidth() => $_has(7); + @$pb.TagNumber(8) + void clearWidth() => clearField(8); + + @$pb.TagNumber(9) + $core.List<$core.int> get typeOptionData => $_getN(8); + @$pb.TagNumber(9) + set typeOptionData($core.List<$core.int> v) { $_setBytes(8, v); } + @$pb.TagNumber(9) + $core.bool hasTypeOptionData() => $_has(8); + @$pb.TagNumber(9) + void clearTypeOptionData() => clearField(9); +} + +enum CellChangeset_OneOfData { + data, + notSet +} + +class CellChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CellChangeset_OneOfData> _CellChangeset_OneOfDataByTag = { + 4 : CellChangeset_OneOfData.data, + 0 : CellChangeset_OneOfData.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellChangeset', createEmptyInstance: create) + ..oo(0, [4]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : '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? gridId, + $core.String? rowId, + $core.String? fieldId, + $core.String? data, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (rowId != null) { + _result.rowId = rowId; + } + 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; + + CellChangeset_OneOfData whichOneOfData() => _CellChangeset_OneOfDataByTag[$_whichOneof(0)]!; + void clearOneOfData() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get 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); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart index 0ea2223329..661b26532c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart @@ -5,3 +5,30 @@ // @dart = 2.12 // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class FieldType extends $pb.ProtobufEnum { + static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); + static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime'); + static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect'); + static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect'); + static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox'); + + static const $core.List values = [ + RichText, + Number, + DateTime, + SingleSelect, + MultiSelect, + Checkbox, + ]; + + static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values); + static FieldType? valueOf($core.int value) => _byValue[value]; + + const FieldType._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 0a565b2b49..de56fa5748 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -8,6 +8,21 @@ 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', @@ -328,3 +343,46 @@ const QueryGridBlocksPayload$json = const { /// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM='); +@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead') +const FieldChangesetPayload$json = const { + '1': 'FieldChangesetPayload', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'}, + const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'}, + const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'}, + const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, + const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, + const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'}, + const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'}, + ], + '8': const [ + const {'1': 'one_of_name'}, + const {'1': 'one_of_desc'}, + const {'1': 'one_of_field_type'}, + const {'1': 'one_of_frozen'}, + const {'1': 'one_of_visibility'}, + const {'1': 'one_of_width'}, + const {'1': 'one_of_type_option_data'}, + ], +}; + +/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ=='); +@$core.Deprecated('Use cellChangesetDescriptor instead') +const CellChangeset$json = const { + '1': 'CellChangeset', + '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': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'data'}, + ], + '8': const [ + const {'1': 'one_of_data'}, + ], +}; + +/// Descriptor for `CellChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellChangesetDescriptor = $convert.base64Decode('Cg1DZWxsQ2hhbmdlc2V0EhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhQKBGRhdGEYBCABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart deleted file mode 100644 index 5ab811fa3f..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ /dev/null @@ -1,1086 +0,0 @@ -/// -// Generated code. Do not modify. -// source: meta.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'meta.pbenum.dart'; - -export 'meta.pbenum.dart'; - -class GridMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) - ..hasRequiredFields = false - ; - - GridMeta._() : super(); - factory GridMeta({ - $core.String? gridId, - $core.Iterable? fields, - $core.Iterable? blocks, - }) { - final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } - if (fields != null) { - _result.fields.addAll(fields); - } - if (blocks != null) { - _result.blocks.addAll(blocks); - } - return _result; - } - factory GridMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GridMeta clone() => GridMeta()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridMeta copyWith(void Function(GridMeta) updates) => super.copyWith((message) => updates(message as GridMeta)) as GridMeta; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridMeta create() => GridMeta._(); - GridMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridMeta? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get gridId => $_getSZ(0); - @$pb.TagNumber(1) - set gridId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasGridId() => $_has(0); - @$pb.TagNumber(1) - void clearGridId() => clearField(1); - - @$pb.TagNumber(2) - $core.List get fields => $_getList(1); - - @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); -} - -class GridBlockMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - GridBlockMeta._() : super(); - factory GridBlockMeta({ - $core.String? blockId, - $core.int? startRowIndex, - $core.int? rowCount, - }) { - final _result = create(); - if (blockId != null) { - _result.blockId = blockId; - } - if (startRowIndex != null) { - _result.startRowIndex = startRowIndex; - } - if (rowCount != null) { - _result.rowCount = rowCount; - } - return _result; - } - factory GridBlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GridBlockMeta clone() => GridBlockMeta()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridBlockMeta copyWith(void Function(GridBlockMeta) updates) => super.copyWith((message) => updates(message as GridBlockMeta)) as GridBlockMeta; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridBlockMeta create() => GridBlockMeta._(); - GridBlockMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridBlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlockMeta? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); - @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); - @$pb.TagNumber(1) - void clearBlockId() => clearField(1); - - @$pb.TagNumber(2) - $core.int get startRowIndex => $_getIZ(1); - @$pb.TagNumber(2) - set startRowIndex($core.int v) { $_setSignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasStartRowIndex() => $_has(1); - @$pb.TagNumber(2) - void clearStartRowIndex() => clearField(2); - - @$pb.TagNumber(3) - $core.int get rowCount => $_getIZ(2); - @$pb.TagNumber(3) - set rowCount($core.int v) { $_setSignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasRowCount() => $_has(2); - @$pb.TagNumber(3) - void clearRowCount() => clearField(3); -} - -class GridBlockMetaData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) - ..hasRequiredFields = false - ; - - GridBlockMetaData._() : super(); - factory GridBlockMetaData({ - $core.String? blockId, - $core.Iterable? rows, - }) { - final _result = create(); - if (blockId != null) { - _result.blockId = blockId; - } - if (rows != null) { - _result.rows.addAll(rows); - } - return _result; - } - factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridBlockMetaData create() => GridBlockMetaData._(); - GridBlockMetaData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlockMetaData? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); - @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); - @$pb.TagNumber(1) - void clearBlockId() => clearField(1); - - @$pb.TagNumber(2) - $core.List get rows => $_getList(1); -} - -class FieldMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') - ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') - ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..m<$core.String, $core.String>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', entryClassName: 'FieldMeta.TypeOptionsEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OS) - ..hasRequiredFields = false - ; - - FieldMeta._() : super(); - factory FieldMeta({ - $core.String? id, - $core.String? name, - $core.String? desc, - FieldType? fieldType, - $core.bool? frozen, - $core.bool? visibility, - $core.int? width, - $core.Map<$core.String, $core.String>? typeOptions, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (desc != null) { - _result.desc = desc; - } - if (fieldType != null) { - _result.fieldType = fieldType; - } - if (frozen != null) { - _result.frozen = frozen; - } - if (visibility != null) { - _result.visibility = visibility; - } - if (width != null) { - _result.width = width; - } - if (typeOptions != null) { - _result.typeOptions.addAll(typeOptions); - } - return _result; - } - factory FieldMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FieldMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - FieldMeta clone() => FieldMeta()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FieldMeta copyWith(void Function(FieldMeta) updates) => super.copyWith((message) => updates(message as FieldMeta)) as FieldMeta; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FieldMeta create() => FieldMeta._(); - FieldMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static FieldMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static FieldMeta? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); - @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); - @$pb.TagNumber(2) - void clearName() => clearField(2); - - @$pb.TagNumber(3) - $core.String get desc => $_getSZ(2); - @$pb.TagNumber(3) - set desc($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasDesc() => $_has(2); - @$pb.TagNumber(3) - void clearDesc() => clearField(3); - - @$pb.TagNumber(4) - FieldType get fieldType => $_getN(3); - @$pb.TagNumber(4) - set fieldType(FieldType v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasFieldType() => $_has(3); - @$pb.TagNumber(4) - void clearFieldType() => clearField(4); - - @$pb.TagNumber(5) - $core.bool get frozen => $_getBF(4); - @$pb.TagNumber(5) - set frozen($core.bool v) { $_setBool(4, v); } - @$pb.TagNumber(5) - $core.bool hasFrozen() => $_has(4); - @$pb.TagNumber(5) - void clearFrozen() => clearField(5); - - @$pb.TagNumber(6) - $core.bool get visibility => $_getBF(5); - @$pb.TagNumber(6) - set visibility($core.bool v) { $_setBool(5, v); } - @$pb.TagNumber(6) - $core.bool hasVisibility() => $_has(5); - @$pb.TagNumber(6) - void clearVisibility() => clearField(6); - - @$pb.TagNumber(7) - $core.int get width => $_getIZ(6); - @$pb.TagNumber(7) - set width($core.int v) { $_setSignedInt32(6, v); } - @$pb.TagNumber(7) - $core.bool hasWidth() => $_has(6); - @$pb.TagNumber(7) - void clearWidth() => clearField(7); - - @$pb.TagNumber(8) - $core.Map<$core.String, $core.String> get typeOptions => $_getMap(7); -} - -enum FieldChangesetPayload_OneOfName { - name, - notSet -} - -enum FieldChangesetPayload_OneOfDesc { - desc, - notSet -} - -enum FieldChangesetPayload_OneOfFieldType { - fieldType, - notSet -} - -enum FieldChangesetPayload_OneOfFrozen { - frozen, - notSet -} - -enum FieldChangesetPayload_OneOfVisibility { - visibility, - notSet -} - -enum FieldChangesetPayload_OneOfWidth { - width, - notSet -} - -enum FieldChangesetPayload_OneOfTypeOptionData { - typeOptionData, - notSet -} - -class FieldChangesetPayload extends $pb.GeneratedMessage { - static const $core.Map<$core.int, FieldChangesetPayload_OneOfName> _FieldChangesetPayload_OneOfNameByTag = { - 3 : FieldChangesetPayload_OneOfName.name, - 0 : FieldChangesetPayload_OneOfName.notSet - }; - static const $core.Map<$core.int, FieldChangesetPayload_OneOfDesc> _FieldChangesetPayload_OneOfDescByTag = { - 4 : FieldChangesetPayload_OneOfDesc.desc, - 0 : FieldChangesetPayload_OneOfDesc.notSet - }; - static const $core.Map<$core.int, FieldChangesetPayload_OneOfFieldType> _FieldChangesetPayload_OneOfFieldTypeByTag = { - 5 : FieldChangesetPayload_OneOfFieldType.fieldType, - 0 : FieldChangesetPayload_OneOfFieldType.notSet - }; - static const $core.Map<$core.int, FieldChangesetPayload_OneOfFrozen> _FieldChangesetPayload_OneOfFrozenByTag = { - 6 : FieldChangesetPayload_OneOfFrozen.frozen, - 0 : FieldChangesetPayload_OneOfFrozen.notSet - }; - static const $core.Map<$core.int, FieldChangesetPayload_OneOfVisibility> _FieldChangesetPayload_OneOfVisibilityByTag = { - 7 : FieldChangesetPayload_OneOfVisibility.visibility, - 0 : FieldChangesetPayload_OneOfVisibility.notSet - }; - static const $core.Map<$core.int, FieldChangesetPayload_OneOfWidth> _FieldChangesetPayload_OneOfWidthByTag = { - 8 : FieldChangesetPayload_OneOfWidth.width, - 0 : FieldChangesetPayload_OneOfWidth.notSet - }; - static const $core.Map<$core.int, FieldChangesetPayload_OneOfTypeOptionData> _FieldChangesetPayload_OneOfTypeOptionDataByTag = { - 9 : FieldChangesetPayload_OneOfTypeOptionData.typeOptionData, - 0 : FieldChangesetPayload_OneOfTypeOptionData.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangesetPayload', createEmptyInstance: create) - ..oo(0, [3]) - ..oo(1, [4]) - ..oo(2, [5]) - ..oo(3, [6]) - ..oo(4, [7]) - ..oo(5, [8]) - ..oo(6, [9]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..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') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) - ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') - ..aOB(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') - ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..a<$core.List<$core.int>>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - FieldChangesetPayload._() : super(); - factory FieldChangesetPayload({ - $core.String? fieldId, - $core.String? gridId, - $core.String? name, - $core.String? desc, - FieldType? fieldType, - $core.bool? frozen, - $core.bool? visibility, - $core.int? width, - $core.List<$core.int>? typeOptionData, - }) { - final _result = create(); - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (gridId != null) { - _result.gridId = gridId; - } - if (name != null) { - _result.name = name; - } - if (desc != null) { - _result.desc = desc; - } - if (fieldType != null) { - _result.fieldType = fieldType; - } - if (frozen != null) { - _result.frozen = frozen; - } - if (visibility != null) { - _result.visibility = visibility; - } - if (width != null) { - _result.width = width; - } - if (typeOptionData != null) { - _result.typeOptionData = typeOptionData; - } - return _result; - } - factory FieldChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FieldChangesetPayload.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') - FieldChangesetPayload clone() => FieldChangesetPayload()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FieldChangesetPayload copyWith(void Function(FieldChangesetPayload) updates) => super.copyWith((message) => updates(message as FieldChangesetPayload)) as FieldChangesetPayload; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FieldChangesetPayload create() => FieldChangesetPayload._(); - FieldChangesetPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static FieldChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static FieldChangesetPayload? _defaultInstance; - - FieldChangesetPayload_OneOfName whichOneOfName() => _FieldChangesetPayload_OneOfNameByTag[$_whichOneof(0)]!; - void clearOneOfName() => clearField($_whichOneof(0)); - - FieldChangesetPayload_OneOfDesc whichOneOfDesc() => _FieldChangesetPayload_OneOfDescByTag[$_whichOneof(1)]!; - void clearOneOfDesc() => clearField($_whichOneof(1)); - - FieldChangesetPayload_OneOfFieldType whichOneOfFieldType() => _FieldChangesetPayload_OneOfFieldTypeByTag[$_whichOneof(2)]!; - void clearOneOfFieldType() => clearField($_whichOneof(2)); - - FieldChangesetPayload_OneOfFrozen whichOneOfFrozen() => _FieldChangesetPayload_OneOfFrozenByTag[$_whichOneof(3)]!; - void clearOneOfFrozen() => clearField($_whichOneof(3)); - - FieldChangesetPayload_OneOfVisibility whichOneOfVisibility() => _FieldChangesetPayload_OneOfVisibilityByTag[$_whichOneof(4)]!; - void clearOneOfVisibility() => clearField($_whichOneof(4)); - - FieldChangesetPayload_OneOfWidth whichOneOfWidth() => _FieldChangesetPayload_OneOfWidthByTag[$_whichOneof(5)]!; - void clearOneOfWidth() => clearField($_whichOneof(5)); - - FieldChangesetPayload_OneOfTypeOptionData whichOneOfTypeOptionData() => _FieldChangesetPayload_OneOfTypeOptionDataByTag[$_whichOneof(6)]!; - void clearOneOfTypeOptionData() => clearField($_whichOneof(6)); - - @$pb.TagNumber(1) - $core.String get fieldId => $_getSZ(0); - @$pb.TagNumber(1) - set fieldId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasFieldId() => $_has(0); - @$pb.TagNumber(1) - void clearFieldId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get gridId => $_getSZ(1); - @$pb.TagNumber(2) - set gridId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasGridId() => $_has(1); - @$pb.TagNumber(2) - void clearGridId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get name => $_getSZ(2); - @$pb.TagNumber(3) - set name($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasName() => $_has(2); - @$pb.TagNumber(3) - void clearName() => clearField(3); - - @$pb.TagNumber(4) - $core.String get desc => $_getSZ(3); - @$pb.TagNumber(4) - set desc($core.String v) { $_setString(3, v); } - @$pb.TagNumber(4) - $core.bool hasDesc() => $_has(3); - @$pb.TagNumber(4) - void clearDesc() => clearField(4); - - @$pb.TagNumber(5) - FieldType get fieldType => $_getN(4); - @$pb.TagNumber(5) - set fieldType(FieldType v) { setField(5, v); } - @$pb.TagNumber(5) - $core.bool hasFieldType() => $_has(4); - @$pb.TagNumber(5) - void clearFieldType() => clearField(5); - - @$pb.TagNumber(6) - $core.bool get frozen => $_getBF(5); - @$pb.TagNumber(6) - set frozen($core.bool v) { $_setBool(5, v); } - @$pb.TagNumber(6) - $core.bool hasFrozen() => $_has(5); - @$pb.TagNumber(6) - void clearFrozen() => clearField(6); - - @$pb.TagNumber(7) - $core.bool get visibility => $_getBF(6); - @$pb.TagNumber(7) - set visibility($core.bool v) { $_setBool(6, v); } - @$pb.TagNumber(7) - $core.bool hasVisibility() => $_has(6); - @$pb.TagNumber(7) - void clearVisibility() => clearField(7); - - @$pb.TagNumber(8) - $core.int get width => $_getIZ(7); - @$pb.TagNumber(8) - set width($core.int v) { $_setSignedInt32(7, v); } - @$pb.TagNumber(8) - $core.bool hasWidth() => $_has(7); - @$pb.TagNumber(8) - void clearWidth() => clearField(8); - - @$pb.TagNumber(9) - $core.List<$core.int> get typeOptionData => $_getN(8); - @$pb.TagNumber(9) - set typeOptionData($core.List<$core.int> v) { $_setBytes(8, v); } - @$pb.TagNumber(9) - $core.bool hasTypeOptionData() => $_has(8); - @$pb.TagNumber(9) - void clearTypeOptionData() => clearField(9); -} - -class AnyData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - AnyData._() : super(); - factory AnyData({ - $core.String? typeId, - $core.List<$core.int>? value, - }) { - final _result = create(); - if (typeId != null) { - _result.typeId = typeId; - } - if (value != null) { - _result.value = value; - } - return _result; - } - factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory AnyData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - AnyData clone() => AnyData()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static AnyData create() => AnyData._(); - AnyData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static AnyData? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get typeId => $_getSZ(0); - @$pb.TagNumber(1) - set typeId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasTypeId() => $_has(0); - @$pb.TagNumber(1) - void clearTypeId() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get value => $_getN(1); - @$pb.TagNumber(2) - set value($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasValue() => $_has(1); - @$pb.TagNumber(2) - void clearValue() => clearField(2); -} - -class RowMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cells', entryClassName: 'RowMeta.CellsEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) - ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') - ..hasRequiredFields = false - ; - - RowMeta._() : super(); - factory RowMeta({ - $core.String? id, - $core.String? blockId, - $core.Map<$core.String, CellMeta>? cells, - $core.int? height, - $core.bool? visibility, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (blockId != null) { - _result.blockId = blockId; - } - if (cells != null) { - _result.cells.addAll(cells); - } - if (height != null) { - _result.height = height; - } - if (visibility != null) { - _result.visibility = visibility; - } - return _result; - } - factory RowMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RowMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RowMeta clone() => RowMeta()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RowMeta copyWith(void Function(RowMeta) updates) => super.copyWith((message) => updates(message as RowMeta)) as RowMeta; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RowMeta create() => RowMeta._(); - RowMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RowMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RowMeta? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get blockId => $_getSZ(1); - @$pb.TagNumber(2) - set blockId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasBlockId() => $_has(1); - @$pb.TagNumber(2) - void clearBlockId() => clearField(2); - - @$pb.TagNumber(3) - $core.Map<$core.String, CellMeta> get cells => $_getMap(2); - - @$pb.TagNumber(4) - $core.int get height => $_getIZ(3); - @$pb.TagNumber(4) - set height($core.int v) { $_setSignedInt32(3, v); } - @$pb.TagNumber(4) - $core.bool hasHeight() => $_has(3); - @$pb.TagNumber(4) - void clearHeight() => clearField(4); - - @$pb.TagNumber(5) - $core.bool get visibility => $_getBF(4); - @$pb.TagNumber(5) - set visibility($core.bool v) { $_setBool(4, v); } - @$pb.TagNumber(5) - $core.bool hasVisibility() => $_has(4); - @$pb.TagNumber(5) - void clearVisibility() => clearField(5); -} - -enum RowMetaChangeset_OneOfHeight { - height, - notSet -} - -enum RowMetaChangeset_OneOfVisibility { - visibility, - notSet -} - -class RowMetaChangeset extends $pb.GeneratedMessage { - static const $core.Map<$core.int, RowMetaChangeset_OneOfHeight> _RowMetaChangeset_OneOfHeightByTag = { - 2 : RowMetaChangeset_OneOfHeight.height, - 0 : RowMetaChangeset_OneOfHeight.notSet - }; - static const $core.Map<$core.int, RowMetaChangeset_OneOfVisibility> _RowMetaChangeset_OneOfVisibilityByTag = { - 3 : RowMetaChangeset_OneOfVisibility.visibility, - 0 : RowMetaChangeset_OneOfVisibility.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMetaChangeset', createEmptyInstance: create) - ..oo(0, [2]) - ..oo(1, [3]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') - ..m<$core.String, CellMeta>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMetaChangeset.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) - ..hasRequiredFields = false - ; - - RowMetaChangeset._() : super(); - factory RowMetaChangeset({ - $core.String? rowId, - $core.int? height, - $core.bool? visibility, - $core.Map<$core.String, CellMeta>? cellByFieldId, - }) { - final _result = create(); - if (rowId != null) { - _result.rowId = rowId; - } - if (height != null) { - _result.height = height; - } - if (visibility != null) { - _result.visibility = visibility; - } - if (cellByFieldId != null) { - _result.cellByFieldId.addAll(cellByFieldId); - } - return _result; - } - factory RowMetaChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RowMetaChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RowMetaChangeset clone() => RowMetaChangeset()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RowMetaChangeset copyWith(void Function(RowMetaChangeset) updates) => super.copyWith((message) => updates(message as RowMetaChangeset)) as RowMetaChangeset; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RowMetaChangeset create() => RowMetaChangeset._(); - RowMetaChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RowMetaChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RowMetaChangeset? _defaultInstance; - - RowMetaChangeset_OneOfHeight whichOneOfHeight() => _RowMetaChangeset_OneOfHeightByTag[$_whichOneof(0)]!; - void clearOneOfHeight() => clearField($_whichOneof(0)); - - RowMetaChangeset_OneOfVisibility whichOneOfVisibility() => _RowMetaChangeset_OneOfVisibilityByTag[$_whichOneof(1)]!; - void clearOneOfVisibility() => clearField($_whichOneof(1)); - - @$pb.TagNumber(1) - $core.String get rowId => $_getSZ(0); - @$pb.TagNumber(1) - set rowId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasRowId() => $_has(0); - @$pb.TagNumber(1) - void clearRowId() => clearField(1); - - @$pb.TagNumber(2) - $core.int get height => $_getIZ(1); - @$pb.TagNumber(2) - set height($core.int v) { $_setSignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasHeight() => $_has(1); - @$pb.TagNumber(2) - void clearHeight() => clearField(2); - - @$pb.TagNumber(3) - $core.bool get visibility => $_getBF(2); - @$pb.TagNumber(3) - set visibility($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasVisibility() => $_has(2); - @$pb.TagNumber(3) - void clearVisibility() => clearField(3); - - @$pb.TagNumber(4) - $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(3); -} - -class CellMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..hasRequiredFields = false - ; - - CellMeta._() : super(); - factory CellMeta({ - $core.String? data, - }) { - final _result = create(); - if (data != null) { - _result.data = data; - } - return _result; - } - factory CellMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CellMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CellMeta clone() => CellMeta()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CellMeta copyWith(void Function(CellMeta) updates) => super.copyWith((message) => updates(message as CellMeta)) as CellMeta; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CellMeta create() => CellMeta._(); - CellMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CellMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CellMeta? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get data => $_getSZ(0); - @$pb.TagNumber(1) - set data($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasData() => $_has(0); - @$pb.TagNumber(1) - void clearData() => clearField(1); -} - -enum CellMetaChangeset_OneOfData { - data, - notSet -} - -class CellMetaChangeset extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CellMetaChangeset_OneOfData> _CellMetaChangeset_OneOfDataByTag = { - 4 : CellMetaChangeset_OneOfData.data, - 0 : CellMetaChangeset_OneOfData.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMetaChangeset', createEmptyInstance: create) - ..oo(0, [4]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..hasRequiredFields = false - ; - - CellMetaChangeset._() : super(); - factory CellMetaChangeset({ - $core.String? gridId, - $core.String? rowId, - $core.String? fieldId, - $core.String? data, - }) { - final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } - if (rowId != null) { - _result.rowId = rowId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (data != null) { - _result.data = data; - } - return _result; - } - factory CellMetaChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CellMetaChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CellMetaChangeset clone() => CellMetaChangeset()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CellMetaChangeset copyWith(void Function(CellMetaChangeset) updates) => super.copyWith((message) => updates(message as CellMetaChangeset)) as CellMetaChangeset; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CellMetaChangeset create() => CellMetaChangeset._(); - CellMetaChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CellMetaChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CellMetaChangeset? _defaultInstance; - - CellMetaChangeset_OneOfData whichOneOfData() => _CellMetaChangeset_OneOfDataByTag[$_whichOneof(0)]!; - void clearOneOfData() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - $core.String get 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.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 BuildGridContext extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMeta', subBuilder: GridBlockMeta.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaData.create) - ..hasRequiredFields = false - ; - - BuildGridContext._() : super(); - factory BuildGridContext({ - $core.Iterable? fieldMetas, - GridBlockMeta? blockMeta, - GridBlockMetaData? blockMetaData, - }) { - final _result = create(); - if (fieldMetas != null) { - _result.fieldMetas.addAll(fieldMetas); - } - if (blockMeta != null) { - _result.blockMeta = blockMeta; - } - if (blockMetaData != null) { - _result.blockMetaData = blockMetaData; - } - return _result; - } - factory BuildGridContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BuildGridContext.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - BuildGridContext clone() => BuildGridContext()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BuildGridContext copyWith(void Function(BuildGridContext) updates) => super.copyWith((message) => updates(message as BuildGridContext)) as BuildGridContext; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BuildGridContext create() => BuildGridContext._(); - BuildGridContext createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static BuildGridContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static BuildGridContext? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get fieldMetas => $_getList(0); - - @$pb.TagNumber(2) - GridBlockMeta get blockMeta => $_getN(1); - @$pb.TagNumber(2) - set blockMeta(GridBlockMeta v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasBlockMeta() => $_has(1); - @$pb.TagNumber(2) - void clearBlockMeta() => clearField(2); - @$pb.TagNumber(2) - GridBlockMeta ensureBlockMeta() => $_ensure(1); - - @$pb.TagNumber(3) - GridBlockMetaData get blockMetaData => $_getN(2); - @$pb.TagNumber(3) - set blockMetaData(GridBlockMetaData v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasBlockMetaData() => $_has(2); - @$pb.TagNumber(3) - void clearBlockMetaData() => clearField(3); - @$pb.TagNumber(3) - GridBlockMetaData ensureBlockMetaData() => $_ensure(2); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart deleted file mode 100644 index 2bb3da475b..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart +++ /dev/null @@ -1,34 +0,0 @@ -/// -// Generated code. Do not modify. -// source: meta.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields - -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class FieldType extends $pb.ProtobufEnum { - static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); - static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); - static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime'); - static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect'); - static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect'); - static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox'); - - static const $core.List values = [ - RichText, - Number, - DateTime, - SingleSelect, - MultiSelect, - Checkbox, - ]; - - static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values); - static FieldType? valueOf($core.int value) => _byValue[value]; - - const FieldType._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart deleted file mode 100644 index 8e73d2ce1c..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ /dev/null @@ -1,217 +0,0 @@ -/// -// Generated code. Do not modify. -// source: meta.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use fieldTypeDescriptor instead') -const FieldType$json = const { - '1': 'FieldType', - '2': const [ - const {'1': 'RichText', '2': 0}, - const {'1': 'Number', '2': 1}, - const {'1': 'DateTime', '2': 2}, - const {'1': 'SingleSelect', '2': 3}, - const {'1': 'MultiSelect', '2': 4}, - const {'1': 'Checkbox', '2': 5}, - ], -}; - -/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ=='); -@$core.Deprecated('Use gridMetaDescriptor instead') -const GridMeta$json = const { - '1': 'GridMeta', - '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, - ], -}; - -/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz'); -@$core.Deprecated('Use gridBlockMetaDescriptor instead') -const GridBlockMeta$json = const { - '1': 'GridBlockMeta', - '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, - const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, - ], -}; - -/// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); -@$core.Deprecated('Use gridBlockMetaDataDescriptor instead') -const GridBlockMetaData$json = const { - '1': 'GridBlockMetaData', - '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, - ], -}; - -/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIcCgRyb3dzGAIgAygLMgguUm93TWV0YVIEcm93cw=='); -@$core.Deprecated('Use fieldMetaDescriptor instead') -const FieldMeta$json = const { - '1': 'FieldMeta', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, - const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, - const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, - const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, - const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 3, '5': 11, '6': '.FieldMeta.TypeOptionsEntry', '10': 'typeOptions'}, - ], - '3': const [FieldMeta_TypeOptionsEntry$json], -}; - -@$core.Deprecated('Use fieldMetaDescriptor instead') -const FieldMeta_TypeOptionsEntry$json = const { - '1': 'TypeOptionsEntry', - '2': const [ - const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, - const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'}, - ], - '7': const {'7': true}, -}; - -/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSPgoMdHlwZV9vcHRpb25zGAggAygLMhsuRmllbGRNZXRhLlR5cGVPcHRpb25zRW50cnlSC3R5cGVPcHRpb25zGj4KEFR5cGVPcHRpb25zRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4AQ=='); -@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead') -const FieldChangesetPayload$json = const { - '1': 'FieldChangesetPayload', - '2': const [ - const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'}, - const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'}, - const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'}, - const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, - const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, - const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'}, - const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'}, - ], - '8': const [ - const {'1': 'one_of_name'}, - const {'1': 'one_of_desc'}, - const {'1': 'one_of_field_type'}, - const {'1': 'one_of_frozen'}, - const {'1': 'one_of_visibility'}, - const {'1': 'one_of_width'}, - const {'1': 'one_of_type_option_data'}, - ], -}; - -/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ=='); -@$core.Deprecated('Use anyDataDescriptor instead') -const AnyData$json = const { - '1': 'AnyData', - '2': const [ - const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'}, - const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, - ], -}; - -/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU='); -@$core.Deprecated('Use rowMetaDescriptor instead') -const RowMeta$json = const { - '1': 'RowMeta', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'cells', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellsEntry', '10': 'cells'}, - const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, - const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'}, - ], - '3': const [RowMeta_CellsEntry$json], -}; - -@$core.Deprecated('Use rowMetaDescriptor instead') -const RowMeta_CellsEntry$json = const { - '1': 'CellsEntry', - '2': const [ - const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, - const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, - ], - '7': const {'7': true}, -}; - -/// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIZCghibG9ja19pZBgCIAEoCVIHYmxvY2tJZBIpCgVjZWxscxgDIAMoCzITLlJvd01ldGEuQ2VsbHNFbnRyeVIFY2VsbHMSFgoGaGVpZ2h0GAQgASgFUgZoZWlnaHQSHgoKdmlzaWJpbGl0eRgFIAEoCFIKdmlzaWJpbGl0eRpDCgpDZWxsc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); -@$core.Deprecated('Use rowMetaChangesetDescriptor instead') -const RowMetaChangeset$json = const { - '1': 'RowMetaChangeset', - '2': const [ - const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'height', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'height'}, - const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '9': 1, '10': 'visibility'}, - const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.RowMetaChangeset.CellByFieldIdEntry', '10': 'cellByFieldId'}, - ], - '3': const [RowMetaChangeset_CellByFieldIdEntry$json], - '8': const [ - const {'1': 'one_of_height'}, - const {'1': 'one_of_visibility'}, - ], -}; - -@$core.Deprecated('Use rowMetaChangesetDescriptor instead') -const RowMetaChangeset_CellByFieldIdEntry$json = const { - '1': 'CellByFieldIdEntry', - '2': const [ - const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, - const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, - ], - '7': const {'7': true}, -}; - -/// Descriptor for `RowMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode('ChBSb3dNZXRhQ2hhbmdlc2V0EhUKBnJvd19pZBgBIAEoCVIFcm93SWQSGAoGaGVpZ2h0GAIgASgFSABSBmhlaWdodBIgCgp2aXNpYmlsaXR5GAMgASgISAFSCnZpc2liaWxpdHkSTQoQY2VsbF9ieV9maWVsZF9pZBgEIAMoCzIkLlJvd01ldGFDaGFuZ2VzZXQuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGksKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIfCgV2YWx1ZRgCIAEoCzIJLkNlbGxNZXRhUgV2YWx1ZToCOAFCDwoNb25lX29mX2hlaWdodEITChFvbmVfb2ZfdmlzaWJpbGl0eQ=='); -@$core.Deprecated('Use cellMetaDescriptor instead') -const CellMeta$json = const { - '1': 'CellMeta', - '2': const [ - const {'1': 'data', '3': 1, '4': 1, '5': 9, '10': 'data'}, - ], -}; - -/// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRISCgRkYXRhGAEgASgJUgRkYXRh'); -@$core.Deprecated('Use cellMetaChangesetDescriptor instead') -const CellMetaChangeset$json = const { - '1': 'CellMetaChangeset', - '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': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'data'}, - ], - '8': const [ - const {'1': 'one_of_data'}, - ], -}; - -/// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIUCgRkYXRhGAQgASgJSABSBGRhdGFCDQoLb25lX29mX2RhdGE='); -@$core.Deprecated('Use buildGridContextDescriptor instead') -const BuildGridContext$json = const { - '1': 'BuildGridContext', - '2': const [ - const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, - const {'1': 'block_meta', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMeta'}, - const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'blockMetaData'}, - ], -}; - -/// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmJsb2NrX21ldGEYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglibG9ja01ldGESOgoPYmxvY2tfbWV0YV9kYXRhGAMgASgLMhIuR3JpZEJsb2NrTWV0YURhdGFSDWJsb2NrTWV0YURhdGE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart deleted file mode 100644 index fdd12ef0bf..0000000000 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: meta.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package - -export 'meta.pb.dart'; - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart index 2c253e0494..3f0100c8d6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart @@ -1,3 +1,2 @@ // Auto-generated, do not edit export './grid.pb.dart'; -export './meta.pb.dart'; diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index a21105a163..a2dc7f826f 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -946,6 +946,7 @@ dependencies = [ "flowy-revision", "flowy-sync", "flowy-test", + "indexmap", "lazy_static", "lib-dispatch", "lib-infra", @@ -971,6 +972,7 @@ dependencies = [ "bytes", "flowy-derive", "flowy-error-code", + "indexmap", "lib-infra", "protobuf", "serde", @@ -1611,12 +1613,13 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", + "serde", ] [[package]] diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index de0320f062..ce72fecb3f 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -34,6 +34,7 @@ rayon = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} serde_repr = "0.1" +indexmap = {version = "1.8.1", features = ["serde"]} [dev-dependencies] flowy-test = { path = "../flowy-test" } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index acc1eeb5c6..abe9dd59a7 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -227,10 +227,10 @@ pub(crate) async fn get_cell_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( - data: Data, + data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let changeset: CellMetaChangeset = data.into_inner(); + let changeset: CellChangeset = data.into_inner(); let editor = manager.get_grid_editor(&changeset.grid_id)?; let _ = editor.update_cell(changeset).await?; Ok(()) @@ -271,7 +271,7 @@ pub(crate) async fn select_option_changeset_handler( field_meta.insert_type_option_entry(&*type_option); let _ = editor.replace_field(field_meta).await?; - let changeset = CellMetaChangeset { + let changeset = CellChangeset { grid_id: changeset.cell_identifier.grid_id, row_id: changeset.cell_identifier.row_id, field_id: changeset.cell_identifier.field_id, @@ -310,7 +310,7 @@ pub(crate) async fn select_option_cell_changeset_handler( ) -> Result<(), FlowyError> { let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let changeset: CellMetaChangeset = params.into(); + let changeset: CellChangeset = params.into(); let _ = editor.update_cell(changeset).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 7246cc7f4f..e2e138aee2 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -92,7 +92,7 @@ pub enum GridEvent { #[event(input = "CellIdentifierPayload", output = "Cell")] GetCell = 70, - #[event(input = "CellMetaChangeset")] + #[event(input = "CellChangeset")] UpdateCell = 71, #[event(input = "SelectOptionCellChangesetPayload")] diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 0c4d1a2efd..b1817c85a6 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -8,7 +8,7 @@ use std::borrow::Cow; use dashmap::DashMap; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, + CellChangeset, CellMeta, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrderChangeset, IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -154,7 +154,7 @@ impl GridBlockMetaEditorManager { Ok(changesets) } - pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + pub async fn update_cell(&self, changeset: CellChangeset) -> FlowyResult<()> { let row_id = changeset.row_id.clone(); let editor = self.get_editor_from_row_id(&row_id).await?; let row_changeset: RowMetaChangeset = changeset.clone().into(); diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index d18e6aa07f..d20e29282e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,7 +1,7 @@ use crate::services::field::type_options::*; use bytes::Bytes; use flowy_grid_data_model::entities::{Field, FieldMeta, FieldType, TypeOptionDataEntry}; -use std::collections::HashMap; +use indexmap::IndexMap; pub struct FieldBuilder { field_meta: FieldMeta, @@ -34,7 +34,7 @@ impl FieldBuilder { frozen: field.frozen, visibility: field.visibility, width: field.width, - type_options: HashMap::default(), + type_options: IndexMap::default(), }; Self { field_meta, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 791ec15718..6a8ad47e4c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -7,7 +7,7 @@ use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError}; use flowy_grid_data_model::entities::{ - CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, + CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, }; use flowy_grid_data_model::parser::NotEmptyUuid; use serde::{Deserialize, Serialize}; @@ -356,14 +356,14 @@ impl SelectOptionCellChangeset { } } -impl std::convert::From for CellMetaChangeset { +impl std::convert::From for CellChangeset { fn from(params: SelectOptionCellChangesetParams) -> Self { let changeset = SelectOptionCellChangeset { insert_option_id: params.insert_option_id, delete_option_id: params.delete_option_id, }; let s = serde_json::to_string(&changeset).unwrap(); - CellMetaChangeset { + CellChangeset { grid_id: params.grid_id, row_id: params.row_id, field_id: params.field_id, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 5984b2552a..27bbd2c2da 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -40,7 +40,7 @@ impl CellDataOperation for RichTextTypeOption { || type_option_cell_data.is_multi_select() || type_option_cell_data.is_number() { - decode_cell_data(data, &field_meta, &type_option_cell_data.field_type).unwrap_or_else(|| "".to_owned()) + decode_cell_data(data, field_meta, &type_option_cell_data.field_type).unwrap_or_else(|| "".to_owned()) } else { type_option_cell_data.data } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index b94efcef99..50282e6b8a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -293,13 +293,15 @@ impl ClientGridEditor { } } - pub async fn update_cell(&self, mut changeset: CellMetaChangeset) -> FlowyResult<()> { + #[tracing::instrument(level = "trace", skip_all, err)] + pub async fn update_cell(&self, mut changeset: CellChangeset) -> FlowyResult<()> { if changeset.data.as_ref().is_none() { return Ok(()); } let cell_data_changeset = changeset.data.unwrap(); let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?; + tracing::trace!("{}: {:?}", &changeset.field_id, cell_meta); match self.pad.read().await.get_field(&changeset.field_id) { None => { let msg = format!("Field not found with id: {}", &changeset.field_id); @@ -431,7 +433,7 @@ impl ClientGridEditor { if let Some(field_meta) = field_metas.pop() { send_dart_notification(field_id, GridNotification::DidUpdateField) - .payload(field_meta) + .payload(Field::from(field_meta)) .send(); } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 2e6970d2c9..23282cdfb1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -3,6 +3,7 @@ use crate::services::row::apply_cell_data_changeset; use crate::services::field::SelectOptionCellChangeset; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; +use indexmap::IndexMap; use std::collections::HashMap; pub struct CreateRowMetaBuilder<'a> { @@ -90,7 +91,7 @@ pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload) pub struct CreateRowMetaPayload { pub row_id: String, - pub cell_by_field_id: HashMap, + pub cell_by_field_id: IndexMap, pub height: i32, pub visibility: bool, } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index e9c75d4f16..770ba758e9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -3,10 +3,7 @@ use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder, }; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; - use std::collections::HashMap; - use std::sync::Arc; pub struct GridBlockSnapshot { @@ -60,7 +57,7 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc>(); diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index a9d7dacec8..aee5a4faa0 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -6,7 +6,7 @@ use flowy_grid::services::field::{ }; use flowy_grid::services::row::{decode_cell_data, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, + CellChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, TypeOptionDataEntry, }; @@ -324,7 +324,7 @@ async fn grid_cell_update() { }; scripts.push(UpdateCell { - changeset: CellMetaChangeset { + changeset: CellChangeset { grid_id: block_id.to_string(), row_id: row_meta.id.clone(), field_id: field_meta.id.clone(), @@ -345,7 +345,7 @@ async fn grid_cell_update() { }; scripts.push(UpdateCell { - changeset: CellMetaChangeset { + changeset: CellChangeset { grid_id: block_id.to_string(), row_id: row_meta.id.clone(), field_id: field_meta.id.clone(), diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 927c505b55..9d2dae5666 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,8 +3,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder, - FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, + BuildGridContext, CellChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, + GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, }; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_sync::client_grid::GridBuilder; @@ -61,7 +61,7 @@ pub enum EditorScript { row_ids: Vec, }, UpdateCell { - changeset: CellMetaChangeset, + changeset: CellChangeset, is_err: bool, }, AssertRowCount(usize), @@ -86,7 +86,7 @@ impl GridEditorTest { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; let build_context = make_template_1_grid(); - let view_data: Bytes = build_context.try_into().unwrap(); + let view_data: Bytes = build_context.into(); let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let field_metas = editor.get_field_metas::(None).await.unwrap(); 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 24af171a92..41835804af 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 @@ -14,7 +14,7 @@ use flowy_folder::{ }; use flowy_grid::manager::{make_grid_view_data, GridManager}; use flowy_grid::util::make_default_grid; -use flowy_grid_data_model::entities::BuildGridContext; + use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -25,6 +25,8 @@ use futures_core::future::BoxFuture; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use std::collections::HashMap; + +use flowy_grid_data_model::entities::BuildGridContext; use std::convert::TryFrom; use std::{convert::TryInto, sync::Arc}; diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 52cb6d081f..08002ff7ca 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -458,6 +458,7 @@ dependencies = [ "bytes", "flowy-derive", "flowy-error-code", + "indexmap", "lib-infra", "protobuf", "serde", @@ -701,6 +702,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" version = "0.3.3" @@ -777,6 +784,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + [[package]] name = "instant" version = "0.1.12" diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index e5a78e41ca..c17ec9ed90 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -16,7 +16,7 @@ serde_json = {version = "1.0"} serde_repr = "0.1" uuid = { version = "0.8", features = ["serde", "v4"] } flowy-error-code = { path = "../flowy-error-code"} - +indexmap = {version = "1.8.1", features = ["serde"]} [build-dependencies] lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] } diff --git a/shared-lib/flowy-grid-data-model/Flowy.toml b/shared-lib/flowy-grid-data-model/Flowy.toml index 5e88aadda5..dcac35f40a 100644 --- a/shared-lib/flowy-grid-data-model/Flowy.toml +++ b/shared-lib/flowy-grid-data-model/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/entities",] +proto_crates = ["src/entities/grid.rs",] event_files = [] \ No newline at end of file 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 d517b7f230..6734062412 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,9 +1,12 @@ -use crate::entities::{FieldMeta, FieldType, RowMeta}; +use crate::entities::{CellMeta, FieldMeta, RowMeta, RowMetaChangeset}; use crate::parser::NotEmptyUuid; -use flowy_derive::ProtoBuf; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; + +use serde_repr::*; use std::collections::HashMap; use std::sync::Arc; +use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { @@ -574,3 +577,169 @@ impl TryInto for QueryGridBlocksPayload { }) } } + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldChangesetPayload { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] + pub grid_id: String, + + #[pb(index = 3, one_of)] + pub name: Option, + + #[pb(index = 4, one_of)] + pub desc: Option, + + #[pb(index = 5, one_of)] + pub field_type: Option, + + #[pb(index = 6, one_of)] + pub frozen: Option, + + #[pb(index = 7, one_of)] + pub visibility: Option, + + #[pb(index = 8, one_of)] + pub width: Option, + + #[pb(index = 9, one_of)] + pub type_option_data: Option>, +} + +#[derive(Debug, Clone, Default)] +pub struct FieldChangesetParams { + pub field_id: String, + + pub grid_id: String, + + pub name: Option, + + pub desc: Option, + + pub field_type: Option, + + pub frozen: Option, + + pub visibility: Option, + + pub width: Option, + + pub type_option_data: Option>, +} + +impl TryInto for FieldChangesetPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + + if let Some(type_option_data) = self.type_option_data.as_ref() { + if type_option_data.is_empty() { + return Err(ErrorCode::TypeOptionDataIsEmpty); + } + } + + Ok(FieldChangesetParams { + field_id: field_id.0, + grid_id: grid_id.0, + name: self.name, + desc: self.desc, + field_type: self.field_type, + frozen: self.frozen, + visibility: self.visibility, + width: self.width, + type_option_data: self.type_option_data, + }) + } +} + +#[derive( + Debug, + Clone, + PartialEq, + Eq, + ProtoBuf_Enum, + EnumCountMacro, + EnumString, + EnumIter, + Display, + Serialize_repr, + Deserialize_repr, +)] +#[repr(u8)] +pub enum FieldType { + RichText = 0, + Number = 1, + DateTime = 2, + SingleSelect = 3, + MultiSelect = 4, + Checkbox = 5, +} + +impl std::default::Default for FieldType { + fn default() -> Self { + FieldType::RichText + } +} + +impl AsRef for FieldType { + fn as_ref(&self) -> &FieldType { + self + } +} + +impl From<&FieldType> for FieldType { + fn from(field_type: &FieldType) -> Self { + field_type.clone() + } +} + +impl FieldType { + pub fn type_id(&self) -> String { + let ty = self.clone(); + format!("{}", ty as u8) + } + + pub fn default_cell_width(&self) -> i32 { + match self { + FieldType::DateTime => 180, + _ => 150, + } + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellChangeset { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] + pub field_id: String, + + #[pb(index = 4, one_of)] + pub data: Option, +} + +impl std::convert::From for RowMetaChangeset { + fn from(changeset: CellChangeset) -> Self { + let mut cell_by_field_id = HashMap::with_capacity(1); + let field_id = changeset.field_id; + let cell_meta = CellMeta { + data: changeset.data.unwrap_or_else(|| "".to_owned()), + }; + cell_by_field_id.insert(field_id, cell_meta); + + RowMetaChangeset { + row_id: changeset.row_id, + height: None, + visibility: None, + cell_by_field_id, + } + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 09fa11c003..31c0e9416c 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,35 +1,24 @@ -use crate::parser::NotEmptyUuid; +use crate::entities::FieldType; + use bytes::Bytes; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error_code::ErrorCode; + +use indexmap::IndexMap; use serde::{Deserialize, Serialize}; -use serde_repr::*; use std::collections::HashMap; -use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 42; -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct GridMeta { - #[pb(index = 1)] pub grid_id: String, - - #[pb(index = 2)] pub fields: Vec, - - #[pb(index = 3)] pub blocks: Vec, } -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct GridBlockMeta { - #[pb(index = 1)] pub block_id: String, - - #[pb(index = 2)] pub start_row_index: i32, - - #[pb(index = 3)] pub row_count: i32, } @@ -68,43 +57,34 @@ impl GridBlockMetaChangeset { } } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct GridBlockMetaData { - #[pb(index = 1)] pub block_id: String, - - #[pb(index = 2)] pub rows: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, Eq, PartialEq)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)] pub struct FieldMeta { - #[pb(index = 1)] pub id: String, - #[pb(index = 2)] pub name: String, - #[pb(index = 3)] pub desc: String, - #[pb(index = 4)] pub field_type: FieldType, - #[pb(index = 5)] pub frozen: bool, - #[pb(index = 6)] pub visibility: bool, - #[pb(index = 7)] pub width: i32, - #[pb(index = 8)] + // #[pb(index = 8)] /// type_options contains key/value pairs /// key: id of the FieldType /// value: type option data string - pub type_options: HashMap, + #[serde(with = "indexmap::serde_seq")] + pub type_options: IndexMap, } impl FieldMeta { @@ -156,180 +136,16 @@ pub trait TypeOptionDataDeserializer { fn from_protobuf_bytes(bytes: Bytes) -> Self; } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct FieldChangesetPayload { - #[pb(index = 1)] - pub field_id: String, - - #[pb(index = 2)] - pub grid_id: String, - - #[pb(index = 3, one_of)] - pub name: Option, - - #[pb(index = 4, one_of)] - pub desc: Option, - - #[pb(index = 5, one_of)] - pub field_type: Option, - - #[pb(index = 6, one_of)] - pub frozen: Option, - - #[pb(index = 7, one_of)] - pub visibility: Option, - - #[pb(index = 8, one_of)] - pub width: Option, - - #[pb(index = 9, one_of)] - pub type_option_data: Option>, -} - -#[derive(Debug, Clone, Default)] -pub struct FieldChangesetParams { - pub field_id: String, - pub grid_id: String, - pub name: Option, - pub desc: Option, - pub field_type: Option, - pub frozen: Option, - pub visibility: Option, - pub width: Option, - pub type_option_data: Option>, -} - -impl TryInto for FieldChangesetPayload { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; - - if let Some(type_option_data) = self.type_option_data.as_ref() { - if type_option_data.is_empty() { - return Err(ErrorCode::TypeOptionDataIsEmpty); - } - } - - Ok(FieldChangesetParams { - field_id: field_id.0, - grid_id: grid_id.0, - name: self.name, - desc: self.desc, - field_type: self.field_type, - frozen: self.frozen, - visibility: self.visibility, - width: self.width, - type_option_data: self.type_option_data, - }) - } -} - -#[derive( - Debug, - Clone, - PartialEq, - Eq, - ProtoBuf_Enum, - EnumCountMacro, - EnumString, - EnumIter, - Display, - Serialize_repr, - Deserialize_repr, -)] -#[repr(u8)] -pub enum FieldType { - RichText = 0, - Number = 1, - DateTime = 2, - SingleSelect = 3, - MultiSelect = 4, - Checkbox = 5, -} - -impl std::default::Default for FieldType { - fn default() -> Self { - FieldType::RichText - } -} - -impl AsRef for FieldType { - fn as_ref(&self) -> &FieldType { - self - } -} - -impl From<&FieldType> for FieldType { - fn from(field_type: &FieldType) -> Self { - field_type.clone() - } -} - -impl FieldType { - pub fn type_id(&self) -> String { - let ty = self.clone(); - format!("{}", ty as u8) - } - - pub fn default_cell_width(&self) -> i32 { - match self { - FieldType::DateTime => 180, - _ => 150, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] -pub struct AnyData { - #[pb(index = 1)] - pub type_id: String, - - #[pb(index = 2)] - pub value: Vec, -} - -impl AnyData { - pub fn from_str>(field_type: F, s: &str) -> AnyData { - Self::from_bytes(field_type, s.as_bytes().to_vec()) - } - - pub fn from_bytes, F: Into>(field_type: F, bytes: T) -> AnyData { - AnyData { - type_id: field_type.into().type_id(), - value: bytes.as_ref().to_vec(), - } - } -} - -impl ToString for AnyData { - fn to_string(&self) -> String { - match String::from_utf8(self.value.clone()) { - Ok(s) => s, - Err(_) => "".to_owned(), - } - } -} - -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct RowMeta { - #[pb(index = 1)] pub id: String, - - #[pb(index = 2)] pub block_id: String, - - #[pb(index = 3)] /// cells contains key/value pairs. /// key: field id, /// value: CellMeta - pub cells: HashMap, - - #[pb(index = 4)] + #[serde(with = "indexmap::serde_seq")] + pub cells: IndexMap, pub height: i32, - - #[pb(index = 5)] pub visibility: bool, } @@ -345,24 +161,16 @@ impl RowMeta { } } -#[derive(Debug, Clone, Default, ProtoBuf)] +#[derive(Debug, Clone, Default)] pub struct RowMetaChangeset { - #[pb(index = 1)] pub row_id: String, - - #[pb(index = 2, one_of)] pub height: Option, - - #[pb(index = 3, one_of)] pub visibility: Option, - - #[pb(index = 4)] pub cell_by_field_id: HashMap, } -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] pub struct CellMeta { - #[pb(index = 1)] pub data: String, } @@ -372,49 +180,27 @@ impl CellMeta { } } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct CellMetaChangeset { - #[pb(index = 1)] - pub grid_id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] - pub field_id: String, - - #[pb(index = 4, one_of)] - pub data: Option, +#[derive(Clone, Deserialize, Serialize)] +pub struct BuildGridContext { + pub field_metas: Vec, + pub block_meta: GridBlockMeta, + pub block_meta_data: GridBlockMetaData, } -impl std::convert::From for RowMetaChangeset { - fn from(changeset: CellMetaChangeset) -> Self { - let mut cell_by_field_id = HashMap::with_capacity(1); - let field_id = changeset.field_id; - let cell_meta = CellMeta { - data: changeset.data.unwrap_or_else(|| "".to_owned()), - }; - cell_by_field_id.insert(field_id, cell_meta); - - RowMetaChangeset { - row_id: changeset.row_id, - height: None, - visibility: None, - cell_by_field_id, - } +impl std::convert::From for Bytes { + fn from(ctx: BuildGridContext) -> Self { + let bytes = serde_json::to_vec(&ctx).unwrap_or_else(|_| vec![]); + Bytes::from(bytes) } } -#[derive(Clone, ProtoBuf)] -pub struct BuildGridContext { - #[pb(index = 1)] - pub field_metas: Vec, +impl std::convert::TryFrom for BuildGridContext { + type Error = serde_json::Error; - #[pb(index = 2)] - pub block_meta: GridBlockMeta, - - #[pb(index = 3)] - pub block_meta_data: GridBlockMetaData, + fn try_from(bytes: Bytes) -> Result { + let ctx: BuildGridContext = serde_json::from_slice(&bytes)?; + Ok(ctx) + } } impl std::default::Default for BuildGridContext { 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 3d86c28702..5d40483fdd 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 @@ -286,7 +286,7 @@ pub struct Field { pub id: ::std::string::String, pub name: ::std::string::String, pub desc: ::std::string::String, - pub field_type: super::meta::FieldType, + pub field_type: FieldType, pub frozen: bool, pub visibility: bool, pub width: i32, @@ -387,15 +387,15 @@ impl Field { // .FieldType field_type = 4; - pub fn get_field_type(&self) -> super::meta::FieldType { + pub fn get_field_type(&self) -> FieldType { self.field_type } pub fn clear_field_type(&mut self) { - self.field_type = super::meta::FieldType::RichText; + self.field_type = FieldType::RichText; } // Param is passed by value, moved - pub fn set_field_type(&mut self, v: super::meta::FieldType) { + pub fn set_field_type(&mut self, v: FieldType) { self.field_type = v; } @@ -508,7 +508,7 @@ impl ::protobuf::Message for Field { if !self.desc.is_empty() { my_size += ::protobuf::rt::string_size(3, &self.desc); } - if self.field_type != super::meta::FieldType::RichText { + if self.field_type != FieldType::RichText { my_size += ::protobuf::rt::enum_size(4, self.field_type); } if self.frozen != false { @@ -535,7 +535,7 @@ impl ::protobuf::Message for Field { if !self.desc.is_empty() { os.write_string(3, &self.desc)?; } - if self.field_type != super::meta::FieldType::RichText { + if self.field_type != FieldType::RichText { os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; } if self.frozen != false { @@ -600,7 +600,7 @@ impl ::protobuf::Message for Field { |m: &Field| { &m.desc }, |m: &mut Field| { &mut m.desc }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + 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 }, @@ -639,7 +639,7 @@ impl ::protobuf::Clear for Field { self.id.clear(); self.name.clear(); self.desc.clear(); - self.field_type = super::meta::FieldType::RichText; + self.field_type = FieldType::RichText; self.frozen = false; self.visibility = false; self.width = 0; @@ -822,7 +822,7 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { pub struct GetEditFieldContextPayload { // message fields pub grid_id: ::std::string::String, - pub field_type: super::meta::FieldType, + pub field_type: FieldType, // message oneof groups pub one_of_field_id: ::std::option::Option, // special fields @@ -924,15 +924,15 @@ impl GetEditFieldContextPayload { // .FieldType field_type = 3; - pub fn get_field_type(&self) -> super::meta::FieldType { + pub fn get_field_type(&self) -> FieldType { self.field_type } pub fn clear_field_type(&mut self) { - self.field_type = super::meta::FieldType::RichText; + self.field_type = FieldType::RichText; } // Param is passed by value, moved - pub fn set_field_type(&mut self, v: super::meta::FieldType) { + pub fn set_field_type(&mut self, v: FieldType) { self.field_type = v; } } @@ -973,7 +973,7 @@ impl ::protobuf::Message for GetEditFieldContextPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if self.field_type != super::meta::FieldType::RichText { + if self.field_type != FieldType::RichText { my_size += ::protobuf::rt::enum_size(3, self.field_type); } if let ::std::option::Option::Some(ref v) = self.one_of_field_id { @@ -992,7 +992,7 @@ impl ::protobuf::Message for GetEditFieldContextPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if self.field_type != super::meta::FieldType::RichText { + if self.field_type != FieldType::RichText { os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.field_type))?; } if let ::std::option::Option::Some(ref v) = self.one_of_field_id { @@ -1050,7 +1050,7 @@ impl ::protobuf::Message for GetEditFieldContextPayload { GetEditFieldContextPayload::has_field_id, GetEditFieldContextPayload::get_field_id, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "field_type", |m: &GetEditFieldContextPayload| { &m.field_type }, |m: &mut GetEditFieldContextPayload| { &mut m.field_type }, @@ -1073,7 +1073,7 @@ impl ::protobuf::Clear for GetEditFieldContextPayload { fn clear(&mut self) { self.grid_id.clear(); self.one_of_field_id = ::std::option::Option::None; - self.field_type = super::meta::FieldType::RichText; + self.field_type = FieldType::RichText; self.unknown_fields.clear(); } } @@ -1095,7 +1095,7 @@ pub struct EditFieldPayload { // message fields pub grid_id: ::std::string::String, pub field_id: ::std::string::String, - pub field_type: super::meta::FieldType, + pub field_type: FieldType, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1167,15 +1167,15 @@ impl EditFieldPayload { // .FieldType field_type = 3; - pub fn get_field_type(&self) -> super::meta::FieldType { + pub fn get_field_type(&self) -> FieldType { self.field_type } pub fn clear_field_type(&mut self) { - self.field_type = super::meta::FieldType::RichText; + self.field_type = FieldType::RichText; } // Param is passed by value, moved - pub fn set_field_type(&mut self, v: super::meta::FieldType) { + pub fn set_field_type(&mut self, v: FieldType) { self.field_type = v; } } @@ -1216,7 +1216,7 @@ impl ::protobuf::Message for EditFieldPayload { if !self.field_id.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.field_id); } - if self.field_type != super::meta::FieldType::RichText { + if self.field_type != FieldType::RichText { my_size += ::protobuf::rt::enum_size(3, self.field_type); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); @@ -1231,7 +1231,7 @@ impl ::protobuf::Message for EditFieldPayload { if !self.field_id.is_empty() { os.write_string(2, &self.field_id)?; } - if self.field_type != super::meta::FieldType::RichText { + if self.field_type != FieldType::RichText { os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.field_type))?; } os.write_unknown_fields(self.get_unknown_fields())?; @@ -1282,7 +1282,7 @@ impl ::protobuf::Message for EditFieldPayload { |m: &EditFieldPayload| { &m.field_id }, |m: &mut EditFieldPayload| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "field_type", |m: &EditFieldPayload| { &m.field_type }, |m: &mut EditFieldPayload| { &mut m.field_type }, @@ -1305,7 +1305,7 @@ impl ::protobuf::Clear for EditFieldPayload { fn clear(&mut self) { self.grid_id.clear(); self.field_id.clear(); - self.field_type = super::meta::FieldType::RichText; + self.field_type = FieldType::RichText; self.unknown_fields.clear(); } } @@ -5839,69 +5839,1146 @@ impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct FieldChangesetPayload { + // message fields + pub field_id: ::std::string::String, + pub grid_id: ::std::string::String, + // message oneof groups + pub one_of_name: ::std::option::Option, + pub one_of_desc: ::std::option::Option, + pub one_of_field_type: ::std::option::Option, + pub one_of_frozen: ::std::option::Option, + pub one_of_visibility: ::std::option::Option, + pub one_of_width: ::std::option::Option, + pub one_of_type_option_data: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a FieldChangesetPayload { + fn default() -> &'a FieldChangesetPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_name { + name(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_desc { + desc(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_field_type { + field_type(FieldType), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_frozen { + frozen(bool), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_visibility { + visibility(bool), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_width { + width(i32), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangesetPayload_oneof_one_of_type_option_data { + type_option_data(::std::vec::Vec), +} + +impl FieldChangesetPayload { + pub fn new() -> FieldChangesetPayload { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string 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()) + } + + // string name = 3; + + + pub fn get_name(&self) -> &str { + match self.one_of_name { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref v)) => v, + _ => "", + } + } + pub fn clear_name(&mut self) { + self.one_of_name = ::std::option::Option::None; + } + + pub fn has_name(&self) -> bool { + match self.one_of_name { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) + } + + // Mutable pointer to the field. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(_)) = self.one_of_name { + } else { + self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(::std::string::String::new())); + } + match self.one_of_name { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + if self.has_name() { + match self.one_of_name.take() { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // string desc = 4; + + + pub fn get_desc(&self) -> &str { + match self.one_of_desc { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref v)) => v, + _ => "", + } + } + pub fn clear_desc(&mut self) { + self.one_of_desc = ::std::option::Option::None; + } + + pub fn has_desc(&self) -> bool { + match self.one_of_desc { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) + } + + // Mutable pointer to the field. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(_)) = self.one_of_desc { + } else { + self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(::std::string::String::new())); + } + match self.one_of_desc { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + if self.has_desc() { + match self.one_of_desc.take() { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // .FieldType field_type = 5; + + + pub fn get_field_type(&self) -> FieldType { + match self.one_of_field_type { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) => v, + _ => FieldType::RichText, + } + } + pub fn clear_field_type(&mut self) { + self.one_of_field_type = ::std::option::Option::None; + } + + pub fn has_field_type(&self) -> bool { + match self.one_of_field_type { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: FieldType) { + self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) + } + + // bool frozen = 6; + + + pub fn get_frozen(&self) -> bool { + match self.one_of_frozen { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) => v, + _ => false, + } + } + pub fn clear_frozen(&mut self) { + self.one_of_frozen = ::std::option::Option::None; + } + + pub fn has_frozen(&self) -> bool { + match self.one_of_frozen { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) + } + + // bool visibility = 7; + + + pub fn get_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) => v, + _ => false, + } + } + pub fn clear_visibility(&mut self) { + self.one_of_visibility = ::std::option::Option::None; + } + + pub fn has_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) + } + + // int32 width = 8; + + + pub fn get_width(&self) -> i32 { + match self.one_of_width { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) => v, + _ => 0, + } + } + pub fn clear_width(&mut self) { + self.one_of_width = ::std::option::Option::None; + } + + pub fn has_width(&self) -> bool { + match self.one_of_width { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) + } + + // bytes type_option_data = 9; + + + pub fn get_type_option_data(&self) -> &[u8] { + match self.one_of_type_option_data { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v)) => v, + _ => &[], + } + } + pub fn clear_type_option_data(&mut self) { + self.one_of_type_option_data = ::std::option::Option::None; + } + + pub fn has_type_option_data(&self) -> bool { + match self.one_of_type_option_data { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_type_option_data(&mut self, v: ::std::vec::Vec) { + self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) + } + + // Mutable pointer to the field. + pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec { + if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(_)) = self.one_of_type_option_data { + } else { + self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(::std::vec::Vec::new())); + } + match self.one_of_type_option_data { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_type_option_data(&mut self) -> ::std::vec::Vec { + if self.has_type_option_data() { + match self.one_of_type_option_data.take() { + ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) => v, + _ => panic!(), + } + } else { + ::std::vec::Vec::new() + } + } +} + +impl ::protobuf::Message for FieldChangesetPayload { + 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 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(is.read_string()?)); + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(is.read_string()?)); + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(is.read_enum()?)); + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(is.read_bool()?)); + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(is.read_bool()?)); + }, + 8 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(is.read_int32()?)); + }, + 9 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(is.read_bytes()?)); + }, + _ => { + ::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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_name { + match v { + &FieldChangesetPayload_oneof_one_of_name::name(ref v) => { + my_size += ::protobuf::rt::string_size(3, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_desc { + match v { + &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => { + my_size += ::protobuf::rt::string_size(4, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_type { + match v { + &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => { + my_size += ::protobuf::rt::enum_size(5, v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_frozen { + match v { + &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => { + my_size += 2; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => { + my_size += 2; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_width { + match v { + &FieldChangesetPayload_oneof_one_of_width::width(v) => { + my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data { + match v { + &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => { + my_size += ::protobuf::rt::bytes_size(9, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_name { + match v { + &FieldChangesetPayload_oneof_one_of_name::name(ref v) => { + os.write_string(3, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_desc { + match v { + &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => { + os.write_string(4, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_type { + match v { + &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => { + os.write_enum(5, ::protobuf::ProtobufEnum::value(&v))?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_frozen { + match v { + &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => { + os.write_bool(6, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => { + os.write_bool(7, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_width { + match v { + &FieldChangesetPayload_oneof_one_of_width::width(v) => { + os.write_int32(8, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data { + match v { + &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => { + os.write_bytes(9, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> FieldChangesetPayload { + FieldChangesetPayload::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: &FieldChangesetPayload| { &m.field_id }, + |m: &mut FieldChangesetPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &FieldChangesetPayload| { &m.grid_id }, + |m: &mut FieldChangesetPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "name", + FieldChangesetPayload::has_name, + FieldChangesetPayload::get_name, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "desc", + FieldChangesetPayload::has_desc, + FieldChangesetPayload::get_desc, + )); + fields.push(::protobuf::reflect::accessor::make_singular_enum_accessor::<_, FieldType>( + "field_type", + FieldChangesetPayload::has_field_type, + FieldChangesetPayload::get_field_type, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "frozen", + FieldChangesetPayload::has_frozen, + FieldChangesetPayload::get_frozen, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "visibility", + FieldChangesetPayload::has_visibility, + FieldChangesetPayload::get_visibility, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "width", + FieldChangesetPayload::has_width, + FieldChangesetPayload::get_width, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor::<_>( + "type_option_data", + FieldChangesetPayload::has_type_option_data, + FieldChangesetPayload::get_type_option_data, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldChangesetPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldChangesetPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldChangesetPayload::new) + } +} + +impl ::protobuf::Clear for FieldChangesetPayload { + fn clear(&mut self) { + self.field_id.clear(); + self.grid_id.clear(); + self.one_of_name = ::std::option::Option::None; + self.one_of_desc = ::std::option::Option::None; + self.one_of_field_type = ::std::option::Option::None; + self.one_of_frozen = ::std::option::Option::None; + self.one_of_visibility = ::std::option::Option::None; + self.one_of_width = ::std::option::Option::None; + self.one_of_type_option_data = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldChangesetPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldChangesetPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct CellChangeset { + // message fields + pub grid_id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_data: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellChangeset { + fn default() -> &'a CellChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CellChangeset_oneof_one_of_data { + data(::std::string::String), +} + +impl CellChangeset { + pub fn new() -> CellChangeset { + ::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()) + } + + // 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 { + match self.one_of_data { + ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(ref v)) => v, + _ => "", + } + } + pub fn clear_data(&mut self) { + self.one_of_data = ::std::option::Option::None; + } + + pub fn has_data(&self) -> bool { + match self.one_of_data { + ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::string::String) { + self.one_of_data = ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(v)) + } + + // Mutable pointer to the field. + pub fn mut_data(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(_)) = self.one_of_data { + } else { + self.one_of_data = ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(::std::string::String::new())); + } + match self.one_of_data { + ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_data(&mut self) -> ::std::string::String { + if self.has_data() { + match self.one_of_data.take() { + ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(v)) => v, + _ => panic!(), + } + } else { + ::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.grid_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 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_data = ::std::option::Option::Some(CellChangeset_oneof_one_of_data::data(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.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.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.field_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_data { + match v { + &CellChangeset_oneof_one_of_data::data(ref v) => { + my_size += ::protobuf::rt::string_size(4, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.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 ::std::option::Option::Some(ref v) = self.one_of_data { + match v { + &CellChangeset_oneof_one_of_data::data(ref v) => { + os.write_string(4, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> 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>( + "grid_id", + |m: &CellChangeset| { &m.grid_id }, + |m: &mut CellChangeset| { &mut m.grid_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_singular_string_accessor::<_>( + "data", + CellChangeset::has_data, + CellChangeset::get_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.grid_id.clear(); + self.row_id.clear(); + self.field_id.clear(); + self.one_of_data = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for 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(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\x1a\nmeta.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ - erR\x0bfieldOrders\x122\n\x0cblock_orders\x18\x03\x20\x03(\x0b2\x0f.Grid\ - BlockOrderR\x0bblockOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\ - \n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\ - \x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\ - \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ - \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEdit\ - FieldContextPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x12\x1b\n\x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_t\ - ype\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field\ - _id\"q\n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\n\ - field_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFie\ - ldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngri\ - d_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_optio\ - n_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ - \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ - edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ - ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ - t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ - \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ - \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ - \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ - .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ - \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ - items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\ - \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\ - \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc5\x01\n\x17GridBlockOr\ - derChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\ - \rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\ - \x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\ - \x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\ - \"_\n\rIndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\ - \x08rowOrder\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\ - \x0cone_of_index\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ - id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\ - \x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\ - \x07content\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificati\ - onData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08f\ - ield_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\ - \x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07content\ - B\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\ - \x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\ - \n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05va\ - lue\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ - \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ - _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\ - \x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12Cre\ - ateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ - \x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type\ - _option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_fie\ - ld_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_fiel\ - d_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFiel\ - dOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_\ - id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\ - \x0b2\x0f.GridBlockOrderR\x0bblockOrdersb\x06proto3\ + \n\ngrid.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrderR\x0bfieldOr\ + ders\x122\n\x0cblock_orders\x18\x03\x20\x03(\x0b2\x0f.GridBlockOrderR\ + \x0bblockOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ + FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ + n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ + idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ + id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldContextPayl\ + oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08fiel\ + d_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\ + \x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\n\x10Edi\ + tFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\ + \n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_type\x18\x03\ + \x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\x02\ + \x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\x03\ + \x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05items\ + \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ + RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ + lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ + yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ + \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ + (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ + \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ + \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ + \x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\x12\x19\n\ + \x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\x18\x02\ + \x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc5\x01\n\x17GridBlockOrderChang\ + eset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\rinsert\ + ed_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\x12,\n\ + \x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\ + \x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"_\n\r\ + IndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08row\ + Order\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone\ + _of_index\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\ + \n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\ + \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07conte\ + nt\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_i\ + d\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ + \x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\ + \x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\ + \x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04nam\ + e\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ + \x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\ + \x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0\ + R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPa\ + yload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05fi\ + eld\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ + \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ + \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ + \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ + \x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPayload\ + \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ + id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0\ + R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfie\ + ld_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06\ + frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\ + \x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\ + \x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\ + \x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one\ + _of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\ + \x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x7f\n\rCellChangese\ + t\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ + \x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\ + \x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone\ + _of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ + \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ + \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ + o3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs deleted file mode 100644 index 3468eb594d..0000000000 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ /dev/null @@ -1,3520 +0,0 @@ -// This file is generated by rust-protobuf 2.25.2. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![cfg_attr(rustfmt, rustfmt::skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `meta.proto` - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; - -#[derive(PartialEq,Clone,Default)] -pub struct GridMeta { - // message fields - pub grid_id: ::std::string::String, - pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GridMeta { - fn default() -> &'a GridMeta { - ::default_instance() - } -} - -impl GridMeta { - pub fn new() -> GridMeta { - ::std::default::Default::default() - } - - // string grid_id = 1; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // repeated .FieldMeta fields = 2; - - - pub fn get_fields(&self) -> &[FieldMeta] { - &self.fields - } - pub fn clear_fields(&mut self) { - self.fields.clear(); - } - - // Param is passed by value, moved - pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { - self.fields = v; - } - - // Mutable pointer to the field. - pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.fields - } - - // Take field - pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) - } - - // repeated .GridBlockMeta blocks = 3; - - - pub fn get_blocks(&self) -> &[GridBlockMeta] { - &self.blocks - } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); - } - - // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; - } - - // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks - } - - // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for GridMeta { - fn is_initialized(&self) -> bool { - for v in &self.fields { - if !v.is_initialized() { - return false; - } - }; - for v in &self.blocks { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; - }, - 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } - for value in &self.fields { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - for value in &self.blocks { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } - for v in &self.fields { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - for v in &self.blocks { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GridMeta { - GridMeta::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &GridMeta| { &m.grid_id }, - |m: &mut GridMeta| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "fields", - |m: &GridMeta| { &m.fields }, - |m: &mut GridMeta| { &mut m.fields }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &GridMeta| { &m.blocks }, - |m: &mut GridMeta| { &mut m.blocks }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridMeta", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GridMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridMeta::new) - } -} - -impl ::protobuf::Clear for GridMeta { - fn clear(&mut self) { - self.grid_id.clear(); - self.fields.clear(); - self.blocks.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GridMeta { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GridMeta { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GridBlockMeta { - // message fields - pub block_id: ::std::string::String, - pub start_row_index: i32, - pub row_count: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GridBlockMeta { - fn default() -> &'a GridBlockMeta { - ::default_instance() - } -} - -impl GridBlockMeta { - pub fn new() -> GridBlockMeta { - ::std::default::Default::default() - } - - // string block_id = 1; - - - pub fn get_block_id(&self) -> &str { - &self.block_id - } - pub fn clear_block_id(&mut self) { - self.block_id.clear(); - } - - // Param is passed by value, moved - pub fn set_block_id(&mut self, v: ::std::string::String) { - self.block_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_id(&mut self) -> &mut ::std::string::String { - &mut self.block_id - } - - // Take field - pub fn take_block_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) - } - - // int32 start_row_index = 2; - - - pub fn get_start_row_index(&self) -> i32 { - self.start_row_index - } - pub fn clear_start_row_index(&mut self) { - self.start_row_index = 0; - } - - // Param is passed by value, moved - pub fn set_start_row_index(&mut self, v: i32) { - self.start_row_index = v; - } - - // int32 row_count = 3; - - - pub fn get_row_count(&self) -> i32 { - self.row_count - } - pub fn clear_row_count(&mut self) { - self.row_count = 0; - } - - // Param is passed by value, moved - pub fn set_row_count(&mut self, v: i32) { - self.row_count = v; - } -} - -impl ::protobuf::Message for GridBlockMeta { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.start_row_index = tmp; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.row_count = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.block_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.block_id); - } - if self.start_row_index != 0 { - my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); - } - if self.row_count != 0 { - my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.block_id.is_empty() { - os.write_string(1, &self.block_id)?; - } - if self.start_row_index != 0 { - os.write_int32(2, self.start_row_index)?; - } - if self.row_count != 0 { - os.write_int32(3, self.row_count)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GridBlockMeta { - GridBlockMeta::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "block_id", - |m: &GridBlockMeta| { &m.block_id }, - |m: &mut GridBlockMeta| { &mut m.block_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "start_row_index", - |m: &GridBlockMeta| { &m.start_row_index }, - |m: &mut GridBlockMeta| { &mut m.start_row_index }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "row_count", - |m: &GridBlockMeta| { &m.row_count }, - |m: &mut GridBlockMeta| { &mut m.row_count }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlockMeta", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GridBlockMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlockMeta::new) - } -} - -impl ::protobuf::Clear for GridBlockMeta { - fn clear(&mut self) { - self.block_id.clear(); - self.start_row_index = 0; - self.row_count = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GridBlockMeta { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GridBlockMetaData { - // message fields - pub block_id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GridBlockMetaData { - fn default() -> &'a GridBlockMetaData { - ::default_instance() - } -} - -impl GridBlockMetaData { - pub fn new() -> GridBlockMetaData { - ::std::default::Default::default() - } - - // string block_id = 1; - - - pub fn get_block_id(&self) -> &str { - &self.block_id - } - pub fn clear_block_id(&mut self) { - self.block_id.clear(); - } - - // Param is passed by value, moved - pub fn set_block_id(&mut self, v: ::std::string::String) { - self.block_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_id(&mut self) -> &mut ::std::string::String { - &mut self.block_id - } - - // Take field - pub fn take_block_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) - } - - // repeated .RowMeta rows = 2; - - - pub fn get_rows(&self) -> &[RowMeta] { - &self.rows - } - pub fn clear_rows(&mut self) { - self.rows.clear(); - } - - // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; - } - - // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows - } - - // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for GridBlockMetaData { - fn is_initialized(&self) -> bool { - for v in &self.rows { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; - }, - 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.block_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.block_id); - } - for value in &self.rows { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.block_id.is_empty() { - os.write_string(1, &self.block_id)?; - } - for v in &self.rows { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GridBlockMetaData { - GridBlockMetaData::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "block_id", - |m: &GridBlockMetaData| { &m.block_id }, - |m: &mut GridBlockMetaData| { &mut m.block_id }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridBlockMetaData| { &m.rows }, - |m: &mut GridBlockMetaData| { &mut m.rows }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlockMetaData", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GridBlockMetaData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlockMetaData::new) - } -} - -impl ::protobuf::Clear for GridBlockMetaData { - fn clear(&mut self) { - self.block_id.clear(); - self.rows.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GridBlockMetaData { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct FieldMeta { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub desc: ::std::string::String, - pub field_type: FieldType, - pub frozen: bool, - pub visibility: bool, - pub width: i32, - pub type_options: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a FieldMeta { - fn default() -> &'a FieldMeta { - ::default_instance() - } -} - -impl FieldMeta { - pub fn new() -> FieldMeta { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string name = 2; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // string desc = 3; - - - pub fn get_desc(&self) -> &str { - &self.desc - } - pub fn clear_desc(&mut self) { - self.desc.clear(); - } - - // Param is passed by value, moved - pub fn set_desc(&mut self, v: ::std::string::String) { - self.desc = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_desc(&mut self) -> &mut ::std::string::String { - &mut self.desc - } - - // Take field - pub fn take_desc(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.desc, ::std::string::String::new()) - } - - // .FieldType field_type = 4; - - - pub fn get_field_type(&self) -> FieldType { - self.field_type - } - pub fn clear_field_type(&mut self) { - self.field_type = FieldType::RichText; - } - - // Param is passed by value, moved - pub fn set_field_type(&mut self, v: FieldType) { - self.field_type = v; - } - - // bool frozen = 5; - - - pub fn get_frozen(&self) -> bool { - self.frozen - } - pub fn clear_frozen(&mut self) { - self.frozen = false; - } - - // Param is passed by value, moved - pub fn set_frozen(&mut self, v: bool) { - self.frozen = v; - } - - // bool visibility = 6; - - - pub fn get_visibility(&self) -> bool { - self.visibility - } - pub fn clear_visibility(&mut self) { - self.visibility = false; - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.visibility = v; - } - - // int32 width = 7; - - - pub fn get_width(&self) -> i32 { - self.width - } - pub fn clear_width(&mut self) { - self.width = 0; - } - - // Param is passed by value, moved - pub fn set_width(&mut self, v: i32) { - self.width = v; - } - - // repeated .FieldMeta.TypeOptionsEntry type_options = 8; - - - pub fn get_type_options(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.type_options - } - pub fn clear_type_options(&mut self) { - self.type_options.clear(); - } - - // Param is passed by value, moved - pub fn set_type_options(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { - self.type_options = v; - } - - // Mutable pointer to the field. - pub fn mut_type_options(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.type_options - } - - // Take field - pub fn take_type_options(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { - ::std::mem::replace(&mut self.type_options, ::std::collections::HashMap::new()) - } -} - -impl ::protobuf::Message for FieldMeta { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; - }, - 4 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.frozen = tmp; - }, - 6 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.visibility = tmp; - }, - 7 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.width = tmp; - }, - 8 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.type_options)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.name); - } - if !self.desc.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.desc); - } - if self.field_type != FieldType::RichText { - my_size += ::protobuf::rt::enum_size(4, self.field_type); - } - if self.frozen != false { - my_size += 2; - } - if self.visibility != false { - my_size += 2; - } - if self.width != 0 { - my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(8, &self.type_options); - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.name.is_empty() { - os.write_string(2, &self.name)?; - } - if !self.desc.is_empty() { - os.write_string(3, &self.desc)?; - } - if self.field_type != FieldType::RichText { - os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; - } - if self.frozen != false { - os.write_bool(5, self.frozen)?; - } - if self.visibility != false { - os.write_bool(6, self.visibility)?; - } - if self.width != 0 { - os.write_int32(7, self.width)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(8, &self.type_options, 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() -> FieldMeta { - FieldMeta::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: &FieldMeta| { &m.id }, - |m: &mut FieldMeta| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &FieldMeta| { &m.name }, - |m: &mut FieldMeta| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "desc", - |m: &FieldMeta| { &m.desc }, - |m: &mut FieldMeta| { &mut m.desc }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "field_type", - |m: &FieldMeta| { &m.field_type }, - |m: &mut FieldMeta| { &mut m.field_type }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "frozen", - |m: &FieldMeta| { &m.frozen }, - |m: &mut FieldMeta| { &mut m.frozen }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "visibility", - |m: &FieldMeta| { &m.visibility }, - |m: &mut FieldMeta| { &mut m.visibility }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "width", - |m: &FieldMeta| { &m.width }, - |m: &mut FieldMeta| { &mut m.width }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( - "type_options", - |m: &FieldMeta| { &m.type_options }, - |m: &mut FieldMeta| { &mut m.type_options }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "FieldMeta", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static FieldMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(FieldMeta::new) - } -} - -impl ::protobuf::Clear for FieldMeta { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.desc.clear(); - self.field_type = FieldType::RichText; - self.frozen = false; - self.visibility = false; - self.width = 0; - self.type_options.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for FieldMeta { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldMeta { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct FieldChangesetPayload { - // message fields - pub field_id: ::std::string::String, - pub grid_id: ::std::string::String, - // message oneof groups - pub one_of_name: ::std::option::Option, - pub one_of_desc: ::std::option::Option, - pub one_of_field_type: ::std::option::Option, - pub one_of_frozen: ::std::option::Option, - pub one_of_visibility: ::std::option::Option, - pub one_of_width: ::std::option::Option, - pub one_of_type_option_data: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a FieldChangesetPayload { - fn default() -> &'a FieldChangesetPayload { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_name { - name(::std::string::String), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_desc { - desc(::std::string::String), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_field_type { - field_type(FieldType), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_frozen { - frozen(bool), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_visibility { - visibility(bool), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_width { - width(i32), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum FieldChangesetPayload_oneof_one_of_type_option_data { - type_option_data(::std::vec::Vec), -} - -impl FieldChangesetPayload { - pub fn new() -> FieldChangesetPayload { - ::std::default::Default::default() - } - - // string field_id = 1; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string 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()) - } - - // string name = 3; - - - pub fn get_name(&self) -> &str { - match self.one_of_name { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref v)) => v, - _ => "", - } - } - pub fn clear_name(&mut self) { - self.one_of_name = ::std::option::Option::None; - } - - pub fn has_name(&self) -> bool { - match self.one_of_name { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) - } - - // Mutable pointer to the field. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(_)) = self.one_of_name { - } else { - self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(::std::string::String::new())); - } - match self.one_of_name { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - if self.has_name() { - match self.one_of_name.take() { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) => v, - _ => panic!(), - } - } else { - ::std::string::String::new() - } - } - - // string desc = 4; - - - pub fn get_desc(&self) -> &str { - match self.one_of_desc { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref v)) => v, - _ => "", - } - } - pub fn clear_desc(&mut self) { - self.one_of_desc = ::std::option::Option::None; - } - - pub fn has_desc(&self) -> bool { - match self.one_of_desc { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_desc(&mut self, v: ::std::string::String) { - self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) - } - - // Mutable pointer to the field. - pub fn mut_desc(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(_)) = self.one_of_desc { - } else { - self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(::std::string::String::new())); - } - match self.one_of_desc { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_desc(&mut self) -> ::std::string::String { - if self.has_desc() { - match self.one_of_desc.take() { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) => v, - _ => panic!(), - } - } else { - ::std::string::String::new() - } - } - - // .FieldType field_type = 5; - - - pub fn get_field_type(&self) -> FieldType { - match self.one_of_field_type { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) => v, - _ => FieldType::RichText, - } - } - pub fn clear_field_type(&mut self) { - self.one_of_field_type = ::std::option::Option::None; - } - - pub fn has_field_type(&self) -> bool { - match self.one_of_field_type { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_field_type(&mut self, v: FieldType) { - self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) - } - - // bool frozen = 6; - - - pub fn get_frozen(&self) -> bool { - match self.one_of_frozen { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) => v, - _ => false, - } - } - pub fn clear_frozen(&mut self) { - self.one_of_frozen = ::std::option::Option::None; - } - - pub fn has_frozen(&self) -> bool { - match self.one_of_frozen { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_frozen(&mut self, v: bool) { - self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) - } - - // bool visibility = 7; - - - pub fn get_visibility(&self) -> bool { - match self.one_of_visibility { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) => v, - _ => false, - } - } - pub fn clear_visibility(&mut self) { - self.one_of_visibility = ::std::option::Option::None; - } - - pub fn has_visibility(&self) -> bool { - match self.one_of_visibility { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) - } - - // int32 width = 8; - - - pub fn get_width(&self) -> i32 { - match self.one_of_width { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) => v, - _ => 0, - } - } - pub fn clear_width(&mut self) { - self.one_of_width = ::std::option::Option::None; - } - - pub fn has_width(&self) -> bool { - match self.one_of_width { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_width(&mut self, v: i32) { - self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) - } - - // bytes type_option_data = 9; - - - pub fn get_type_option_data(&self) -> &[u8] { - match self.one_of_type_option_data { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v)) => v, - _ => &[], - } - } - pub fn clear_type_option_data(&mut self) { - self.one_of_type_option_data = ::std::option::Option::None; - } - - pub fn has_type_option_data(&self) -> bool { - match self.one_of_type_option_data { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_type_option_data(&mut self, v: ::std::vec::Vec) { - self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) - } - - // Mutable pointer to the field. - pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec { - if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(_)) = self.one_of_type_option_data { - } else { - self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(::std::vec::Vec::new())); - } - match self.one_of_type_option_data { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_type_option_data(&mut self) -> ::std::vec::Vec { - if self.has_type_option_data() { - match self.one_of_type_option_data.take() { - ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) => v, - _ => panic!(), - } - } else { - ::std::vec::Vec::new() - } - } -} - -impl ::protobuf::Message for FieldChangesetPayload { - 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 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(is.read_string()?)); - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(is.read_string()?)); - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(is.read_enum()?)); - }, - 6 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(is.read_bool()?)); - }, - 7 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(is.read_bool()?)); - }, - 8 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(is.read_int32()?)); - }, - 9 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(is.read_bytes()?)); - }, - _ => { - ::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.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_id); - } - if let ::std::option::Option::Some(ref v) = self.one_of_name { - match v { - &FieldChangesetPayload_oneof_one_of_name::name(ref v) => { - my_size += ::protobuf::rt::string_size(3, &v); - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_desc { - match v { - &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => { - my_size += ::protobuf::rt::string_size(4, &v); - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_field_type { - match v { - &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => { - my_size += ::protobuf::rt::enum_size(5, v); - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_frozen { - match v { - &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => { - my_size += 2; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_visibility { - match v { - &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => { - my_size += 2; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_width { - match v { - &FieldChangesetPayload_oneof_one_of_width::width(v) => { - my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint); - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data { - match v { - &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => { - my_size += ::protobuf::rt::bytes_size(9, &v); - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.field_id.is_empty() { - os.write_string(1, &self.field_id)?; - } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_id)?; - } - if let ::std::option::Option::Some(ref v) = self.one_of_name { - match v { - &FieldChangesetPayload_oneof_one_of_name::name(ref v) => { - os.write_string(3, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_desc { - match v { - &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => { - os.write_string(4, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_field_type { - match v { - &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => { - os.write_enum(5, ::protobuf::ProtobufEnum::value(&v))?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_frozen { - match v { - &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => { - os.write_bool(6, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_visibility { - match v { - &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => { - os.write_bool(7, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_width { - match v { - &FieldChangesetPayload_oneof_one_of_width::width(v) => { - os.write_int32(8, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data { - match v { - &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => { - os.write_bytes(9, v)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> FieldChangesetPayload { - FieldChangesetPayload::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: &FieldChangesetPayload| { &m.field_id }, - |m: &mut FieldChangesetPayload| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &FieldChangesetPayload| { &m.grid_id }, - |m: &mut FieldChangesetPayload| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "name", - FieldChangesetPayload::has_name, - FieldChangesetPayload::get_name, - )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "desc", - FieldChangesetPayload::has_desc, - FieldChangesetPayload::get_desc, - )); - fields.push(::protobuf::reflect::accessor::make_singular_enum_accessor::<_, FieldType>( - "field_type", - FieldChangesetPayload::has_field_type, - FieldChangesetPayload::get_field_type, - )); - fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( - "frozen", - FieldChangesetPayload::has_frozen, - FieldChangesetPayload::get_frozen, - )); - fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( - "visibility", - FieldChangesetPayload::has_visibility, - FieldChangesetPayload::get_visibility, - )); - fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( - "width", - FieldChangesetPayload::has_width, - FieldChangesetPayload::get_width, - )); - fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor::<_>( - "type_option_data", - FieldChangesetPayload::has_type_option_data, - FieldChangesetPayload::get_type_option_data, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "FieldChangesetPayload", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static FieldChangesetPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(FieldChangesetPayload::new) - } -} - -impl ::protobuf::Clear for FieldChangesetPayload { - fn clear(&mut self) { - self.field_id.clear(); - self.grid_id.clear(); - self.one_of_name = ::std::option::Option::None; - self.one_of_desc = ::std::option::Option::None; - self.one_of_field_type = ::std::option::Option::None; - self.one_of_frozen = ::std::option::Option::None; - self.one_of_visibility = ::std::option::Option::None; - self.one_of_width = ::std::option::Option::None; - self.one_of_type_option_data = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for FieldChangesetPayload { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldChangesetPayload { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct AnyData { - // message fields - pub type_id: ::std::string::String, - pub value: ::std::vec::Vec, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a AnyData { - fn default() -> &'a AnyData { - ::default_instance() - } -} - -impl AnyData { - pub fn new() -> AnyData { - ::std::default::Default::default() - } - - // string type_id = 1; - - - pub fn get_type_id(&self) -> &str { - &self.type_id - } - pub fn clear_type_id(&mut self) { - self.type_id.clear(); - } - - // Param is passed by value, moved - pub fn set_type_id(&mut self, v: ::std::string::String) { - self.type_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_type_id(&mut self) -> &mut ::std::string::String { - &mut self.type_id - } - - // Take field - pub fn take_type_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_id, ::std::string::String::new()) - } - - // bytes value = 2; - - - pub fn get_value(&self) -> &[u8] { - &self.value - } - pub fn clear_value(&mut self) { - self.value.clear(); - } - - // Param is passed by value, moved - pub fn set_value(&mut self, v: ::std::vec::Vec) { - self.value = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_value(&mut self) -> &mut ::std::vec::Vec { - &mut self.value - } - - // Take field - pub fn take_value(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.value, ::std::vec::Vec::new()) - } -} - -impl ::protobuf::Message for AnyData { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.value)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.type_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.type_id); - } - if !self.value.is_empty() { - my_size += ::protobuf::rt::bytes_size(2, &self.value); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.type_id.is_empty() { - os.write_string(1, &self.type_id)?; - } - if !self.value.is_empty() { - os.write_bytes(2, &self.value)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> AnyData { - AnyData::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_id", - |m: &AnyData| { &m.type_id }, - |m: &mut AnyData| { &mut m.type_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "value", - |m: &AnyData| { &m.value }, - |m: &mut AnyData| { &mut m.value }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "AnyData", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static AnyData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(AnyData::new) - } -} - -impl ::protobuf::Clear for AnyData { - fn clear(&mut self) { - self.type_id.clear(); - self.value.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for AnyData { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for AnyData { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RowMeta { - // message fields - pub id: ::std::string::String, - pub block_id: ::std::string::String, - pub cells: ::std::collections::HashMap<::std::string::String, CellMeta>, - pub height: i32, - pub visibility: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RowMeta { - fn default() -> &'a RowMeta { - ::default_instance() - } -} - -impl RowMeta { - pub fn new() -> RowMeta { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string block_id = 2; - - - pub fn get_block_id(&self) -> &str { - &self.block_id - } - pub fn clear_block_id(&mut self) { - self.block_id.clear(); - } - - // Param is passed by value, moved - pub fn set_block_id(&mut self, v: ::std::string::String) { - self.block_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_id(&mut self) -> &mut ::std::string::String { - &mut self.block_id - } - - // Take field - pub fn take_block_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) - } - - // repeated .RowMeta.CellsEntry cells = 3; - - - pub fn get_cells(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { - &self.cells - } - pub fn clear_cells(&mut self) { - self.cells.clear(); - } - - // Param is passed by value, moved - pub fn set_cells(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { - self.cells = v; - } - - // Mutable pointer to the field. - pub fn mut_cells(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { - &mut self.cells - } - - // Take field - pub fn take_cells(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { - ::std::mem::replace(&mut self.cells, ::std::collections::HashMap::new()) - } - - // int32 height = 4; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; - } - - // bool visibility = 5; - - - pub fn get_visibility(&self) -> bool { - self.visibility - } - pub fn clear_visibility(&mut self) { - self.visibility = false; - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.visibility = v; - } -} - -impl ::protobuf::Message for RowMeta { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; - }, - 3 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cells)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.visibility = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.block_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.block_id); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cells); - if self.height != 0 { - my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); - } - if self.visibility != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.block_id.is_empty() { - os.write_string(2, &self.block_id)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cells, os)?; - if self.height != 0 { - os.write_int32(4, self.height)?; - } - if self.visibility != false { - os.write_bool(5, self.visibility)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RowMeta { - RowMeta::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &RowMeta| { &m.id }, - |m: &mut RowMeta| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "block_id", - |m: &RowMeta| { &m.block_id }, - |m: &mut RowMeta| { &mut m.block_id }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "cells", - |m: &RowMeta| { &m.cells }, - |m: &mut RowMeta| { &mut m.cells }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &RowMeta| { &m.height }, - |m: &mut RowMeta| { &mut m.height }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "visibility", - |m: &RowMeta| { &m.visibility }, - |m: &mut RowMeta| { &mut m.visibility }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RowMeta", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RowMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RowMeta::new) - } -} - -impl ::protobuf::Clear for RowMeta { - fn clear(&mut self) { - self.id.clear(); - self.block_id.clear(); - self.cells.clear(); - self.height = 0; - self.visibility = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RowMeta { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RowMeta { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RowMetaChangeset { - // message fields - pub row_id: ::std::string::String, - pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, - // message oneof groups - pub one_of_height: ::std::option::Option, - pub one_of_visibility: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RowMetaChangeset { - fn default() -> &'a RowMetaChangeset { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum RowMetaChangeset_oneof_one_of_height { - height(i32), -} - -#[derive(Clone,PartialEq,Debug)] -pub enum RowMetaChangeset_oneof_one_of_visibility { - visibility(bool), -} - -impl RowMetaChangeset { - pub fn new() -> RowMetaChangeset { - ::std::default::Default::default() - } - - // string row_id = 1; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // int32 height = 2; - - - pub fn get_height(&self) -> i32 { - match self.one_of_height { - ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(v)) => v, - _ => 0, - } - } - pub fn clear_height(&mut self) { - self.one_of_height = ::std::option::Option::None; - } - - pub fn has_height(&self) -> bool { - match self.one_of_height { - ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.one_of_height = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(v)) - } - - // bool visibility = 3; - - - pub fn get_visibility(&self) -> bool { - match self.one_of_visibility { - ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(v)) => v, - _ => false, - } - } - pub fn clear_visibility(&mut self) { - self.one_of_visibility = ::std::option::Option::None; - } - - pub fn has_visibility(&self) -> bool { - match self.one_of_visibility { - ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.one_of_visibility = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(v)) - } - - // repeated .RowMetaChangeset.CellByFieldIdEntry cell_by_field_id = 4; - - - pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { - &self.cell_by_field_id - } - pub fn clear_cell_by_field_id(&mut self) { - self.cell_by_field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { - self.cell_by_field_id = v; - } - - // Mutable pointer to the field. - pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { - &mut self.cell_by_field_id - } - - // Take field - pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { - ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) - } -} - -impl ::protobuf::Message for RowMetaChangeset { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_height = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(is.read_int32()?)); - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_visibility = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); - }, - 4 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.row_id); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id); - if let ::std::option::Option::Some(ref v) = self.one_of_height { - match v { - &RowMetaChangeset_oneof_one_of_height::height(v) => { - my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint); - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_visibility { - match v { - &RowMetaChangeset_oneof_one_of_visibility::visibility(v) => { - my_size += 2; - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.row_id.is_empty() { - os.write_string(1, &self.row_id)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, os)?; - if let ::std::option::Option::Some(ref v) = self.one_of_height { - match v { - &RowMetaChangeset_oneof_one_of_height::height(v) => { - os.write_int32(2, v)?; - }, - }; - } - if let ::std::option::Option::Some(ref v) = self.one_of_visibility { - match v { - &RowMetaChangeset_oneof_one_of_visibility::visibility(v) => { - os.write_bool(3, v)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RowMetaChangeset { - RowMetaChangeset::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &RowMetaChangeset| { &m.row_id }, - |m: &mut RowMetaChangeset| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( - "height", - RowMetaChangeset::has_height, - RowMetaChangeset::get_height, - )); - fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( - "visibility", - RowMetaChangeset::has_visibility, - RowMetaChangeset::get_visibility, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "cell_by_field_id", - |m: &RowMetaChangeset| { &m.cell_by_field_id }, - |m: &mut RowMetaChangeset| { &mut m.cell_by_field_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RowMetaChangeset", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RowMetaChangeset { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RowMetaChangeset::new) - } -} - -impl ::protobuf::Clear for RowMetaChangeset { - fn clear(&mut self) { - self.row_id.clear(); - self.one_of_height = ::std::option::Option::None; - self.one_of_visibility = ::std::option::Option::None; - self.cell_by_field_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RowMetaChangeset { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RowMetaChangeset { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct CellMeta { - // message fields - pub data: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CellMeta { - fn default() -> &'a CellMeta { - ::default_instance() - } -} - -impl CellMeta { - pub fn new() -> CellMeta { - ::std::default::Default::default() - } - - // string data = 1; - - - 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 CellMeta { - 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.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.data.is_empty() { - my_size += ::protobuf::rt::string_size(1, &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.data.is_empty() { - os.write_string(1, &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() -> CellMeta { - CellMeta::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "data", - |m: &CellMeta| { &m.data }, - |m: &mut CellMeta| { &mut m.data }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CellMeta", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CellMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CellMeta::new) - } -} - -impl ::protobuf::Clear for CellMeta { - fn clear(&mut self) { - self.data.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CellMeta { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CellMeta { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct CellMetaChangeset { - // message fields - pub grid_id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - // message oneof groups - pub one_of_data: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CellMetaChangeset { - fn default() -> &'a CellMetaChangeset { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum CellMetaChangeset_oneof_one_of_data { - data(::std::string::String), -} - -impl CellMetaChangeset { - pub fn new() -> CellMetaChangeset { - ::std::default::Default::default() - } - - // string 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()) - } - - // 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 { - match self.one_of_data { - ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(ref v)) => v, - _ => "", - } - } - pub fn clear_data(&mut self) { - self.one_of_data = ::std::option::Option::None; - } - - pub fn has_data(&self) -> bool { - match self.one_of_data { - ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(v)) - } - - // Mutable pointer to the field. - pub fn mut_data(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(_)) = self.one_of_data { - } else { - self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(::std::string::String::new())); - } - match self.one_of_data { - ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_data(&mut self) -> ::std::string::String { - if self.has_data() { - match self.one_of_data.take() { - ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(v)) => v, - _ => panic!(), - } - } else { - ::std::string::String::new() - } - } -} - -impl ::protobuf::Message for CellMetaChangeset { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(is.read_string()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.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.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); - } - if let ::std::option::Option::Some(ref v) = self.one_of_data { - match v { - &CellMetaChangeset_oneof_one_of_data::data(ref v) => { - my_size += ::protobuf::rt::string_size(4, &v); - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } - if !self.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 ::std::option::Option::Some(ref v) = self.one_of_data { - match v { - &CellMetaChangeset_oneof_one_of_data::data(ref v) => { - os.write_string(4, v)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CellMetaChangeset { - CellMetaChangeset::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &CellMetaChangeset| { &m.grid_id }, - |m: &mut CellMetaChangeset| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellMetaChangeset| { &m.row_id }, - |m: &mut CellMetaChangeset| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &CellMetaChangeset| { &m.field_id }, - |m: &mut CellMetaChangeset| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "data", - CellMetaChangeset::has_data, - CellMetaChangeset::get_data, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CellMetaChangeset", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CellMetaChangeset { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CellMetaChangeset::new) - } -} - -impl ::protobuf::Clear for CellMetaChangeset { - fn clear(&mut self) { - self.grid_id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.one_of_data = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CellMetaChangeset { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct BuildGridContext { - // message fields - pub field_metas: ::protobuf::RepeatedField, - pub block_meta: ::protobuf::SingularPtrField, - pub block_meta_data: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a BuildGridContext { - fn default() -> &'a BuildGridContext { - ::default_instance() - } -} - -impl BuildGridContext { - pub fn new() -> BuildGridContext { - ::std::default::Default::default() - } - - // repeated .FieldMeta field_metas = 1; - - - pub fn get_field_metas(&self) -> &[FieldMeta] { - &self.field_metas - } - pub fn clear_field_metas(&mut self) { - self.field_metas.clear(); - } - - // Param is passed by value, moved - pub fn set_field_metas(&mut self, v: ::protobuf::RepeatedField) { - self.field_metas = v; - } - - // Mutable pointer to the field. - pub fn mut_field_metas(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.field_metas - } - - // Take field - pub fn take_field_metas(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) - } - - // .GridBlockMeta block_meta = 2; - - - pub fn get_block_meta(&self) -> &GridBlockMeta { - self.block_meta.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_block_meta(&mut self) { - self.block_meta.clear(); - } - - pub fn has_block_meta(&self) -> bool { - self.block_meta.is_some() - } - - // Param is passed by value, moved - pub fn set_block_meta(&mut self, v: GridBlockMeta) { - self.block_meta = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_meta(&mut self) -> &mut GridBlockMeta { - if self.block_meta.is_none() { - self.block_meta.set_default(); - } - self.block_meta.as_mut().unwrap() - } - - // Take field - pub fn take_block_meta(&mut self) -> GridBlockMeta { - self.block_meta.take().unwrap_or_else(|| GridBlockMeta::new()) - } - - // .GridBlockMetaData block_meta_data = 3; - - - pub fn get_block_meta_data(&self) -> &GridBlockMetaData { - self.block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_block_meta_data(&mut self) { - self.block_meta_data.clear(); - } - - pub fn has_block_meta_data(&self) -> bool { - self.block_meta_data.is_some() - } - - // Param is passed by value, moved - pub fn set_block_meta_data(&mut self, v: GridBlockMetaData) { - self.block_meta_data = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_meta_data(&mut self) -> &mut GridBlockMetaData { - if self.block_meta_data.is_none() { - self.block_meta_data.set_default(); - } - self.block_meta_data.as_mut().unwrap() - } - - // Take field - pub fn take_block_meta_data(&mut self) -> GridBlockMetaData { - self.block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new()) - } -} - -impl ::protobuf::Message for BuildGridContext { - fn is_initialized(&self) -> bool { - for v in &self.field_metas { - if !v.is_initialized() { - return false; - } - }; - for v in &self.block_meta { - if !v.is_initialized() { - return false; - } - }; - for v in &self.block_meta_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_repeated_message_into(wire_type, is, &mut self.field_metas)?; - }, - 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta)?; - }, - 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta_data)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.field_metas { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - if let Some(ref v) = self.block_meta.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if let Some(ref v) = self.block_meta_data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.field_metas { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - if let Some(ref v) = self.block_meta.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.block_meta_data.as_ref() { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> BuildGridContext { - BuildGridContext::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "field_metas", - |m: &BuildGridContext| { &m.field_metas }, - |m: &mut BuildGridContext| { &mut m.field_metas }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "block_meta", - |m: &BuildGridContext| { &m.block_meta }, - |m: &mut BuildGridContext| { &mut m.block_meta }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "block_meta_data", - |m: &BuildGridContext| { &m.block_meta_data }, - |m: &mut BuildGridContext| { &mut m.block_meta_data }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BuildGridContext", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static BuildGridContext { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BuildGridContext::new) - } -} - -impl ::protobuf::Clear for BuildGridContext { - fn clear(&mut self) { - self.field_metas.clear(); - self.block_meta.clear(); - self.block_meta_data.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for BuildGridContext { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for BuildGridContext { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum FieldType { - RichText = 0, - Number = 1, - DateTime = 2, - SingleSelect = 3, - MultiSelect = 4, - Checkbox = 5, -} - -impl ::protobuf::ProtobufEnum for FieldType { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(FieldType::RichText), - 1 => ::std::option::Option::Some(FieldType::Number), - 2 => ::std::option::Option::Some(FieldType::DateTime), - 3 => ::std::option::Option::Some(FieldType::SingleSelect), - 4 => ::std::option::Option::Some(FieldType::MultiSelect), - 5 => ::std::option::Option::Some(FieldType::Checkbox), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [FieldType] = &[ - FieldType::RichText, - FieldType::Number, - FieldType::DateTime, - FieldType::SingleSelect, - FieldType::MultiSelect, - FieldType::Checkbox, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("FieldType", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for FieldType { -} - -impl ::std::default::Default for FieldType { - fn default() -> Self { - FieldType::RichText - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldType { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ - s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\ - \n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ - \x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\ - \n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"L\n\x11GridBlockMetaDat\ - a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\ - \x18\x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xbc\x02\n\tFieldMeta\x12\ - \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01\ - (\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield\ - _type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\ - \x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\ - \x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12>\ - \n\x0ctype_options\x18\x08\x20\x03(\x0b2\x1b.FieldMeta.TypeOptionsEntryR\ - \x0btypeOptions\x1a>\n\x10TypeOptionsEntry\x12\x10\n\x03key\x18\x01\x20\ - \x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\x028\ - \x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\ - \x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06grid\ - Id\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\ - \x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\ - \x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\ - \x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nv\ - isibility\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\ - \x10type_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0b\ - one_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_\ - of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17o\ - ne_of_type_option_data\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\ - \x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\ - \xdc\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\ - \n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12)\n\x05cells\x18\x03\ - \x20\x03(\x0b2\x13.RowMeta.CellsEntryR\x05cells\x12\x16\n\x06height\x18\ - \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ - \nvisibility\x1aC\n\nCellsEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03\ - key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\ - \x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01\ - (\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\ - \x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell\ - _by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\ - \rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ - \x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\ - \x1e\n\x08CellMeta\x12\x12\n\x04data\x18\x01\x20\x01(\tR\x04data\"\x83\ - \x01\n\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06\ - gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ - ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\ - \tH\0R\x04dataB\r\n\x0bone_of_data\"\xaa\x01\n\x10BuildGridContext\x12+\ - \n\x0bfield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ - \nblock_meta\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tblockMeta\x12:\n\ - \x0fblock_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\rblockM\ - etaData*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; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) -} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs index d011b76000..7b56c6cee8 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs @@ -3,6 +3,3 @@ mod grid; pub use grid::*; - -mod meta; -pub use meta::*; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index cad2a6a108..a616ea8fd9 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,5 +1,4 @@ syntax = "proto3"; -import "meta.proto"; message Grid { string id = 1; @@ -113,3 +112,28 @@ message QueryGridBlocksPayload { string grid_id = 1; repeated GridBlockOrder block_orders = 2; } +message FieldChangesetPayload { + string field_id = 1; + string grid_id = 2; + oneof one_of_name { string name = 3; }; + oneof one_of_desc { string desc = 4; }; + oneof one_of_field_type { FieldType field_type = 5; }; + oneof one_of_frozen { bool frozen = 6; }; + oneof one_of_visibility { bool visibility = 7; }; + oneof one_of_width { int32 width = 8; }; + oneof one_of_type_option_data { bytes type_option_data = 9; }; +} +message CellChangeset { + string grid_id = 1; + string row_id = 2; + string field_id = 3; + oneof one_of_data { string data = 4; }; +} +enum FieldType { + RichText = 0; + Number = 1; + DateTime = 2; + SingleSelect = 3; + MultiSelect = 4; + Checkbox = 5; +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto deleted file mode 100644 index dcc8d5f91c..0000000000 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ /dev/null @@ -1,76 +0,0 @@ -syntax = "proto3"; - -message GridMeta { - string grid_id = 1; - repeated FieldMeta fields = 2; - repeated GridBlockMeta blocks = 3; -} -message GridBlockMeta { - string block_id = 1; - int32 start_row_index = 2; - int32 row_count = 3; -} -message GridBlockMetaData { - string block_id = 1; - repeated RowMeta rows = 2; -} -message FieldMeta { - string id = 1; - string name = 2; - string desc = 3; - FieldType field_type = 4; - bool frozen = 5; - bool visibility = 6; - int32 width = 7; - map type_options = 8; -} -message FieldChangesetPayload { - string field_id = 1; - string grid_id = 2; - oneof one_of_name { string name = 3; }; - oneof one_of_desc { string desc = 4; }; - oneof one_of_field_type { FieldType field_type = 5; }; - oneof one_of_frozen { bool frozen = 6; }; - oneof one_of_visibility { bool visibility = 7; }; - oneof one_of_width { int32 width = 8; }; - oneof one_of_type_option_data { bytes type_option_data = 9; }; -} -message AnyData { - string type_id = 1; - bytes value = 2; -} -message RowMeta { - string id = 1; - string block_id = 2; - map cells = 3; - int32 height = 4; - bool visibility = 5; -} -message RowMetaChangeset { - string row_id = 1; - oneof one_of_height { int32 height = 2; }; - oneof one_of_visibility { bool visibility = 3; }; - map cell_by_field_id = 4; -} -message CellMeta { - string data = 1; -} -message CellMetaChangeset { - string grid_id = 1; - string row_id = 2; - string field_id = 3; - oneof one_of_data { string data = 4; }; -} -message BuildGridContext { - repeated FieldMeta field_metas = 1; - GridBlockMeta block_meta = 2; - GridBlockMetaData block_meta_data = 3; -} -enum FieldType { - RichText = 0; - Number = 1; - DateTime = 2; - SingleSelect = 3; - MultiSelect = 4; - Checkbox = 5; -} diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 7a06551525..84d3fb2381 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -166,7 +166,7 @@ impl GridBlockMetaPad { tracing::debug!("[GridBlockMeta] Composing delta {}", delta.to_delta_str()); tracing::debug!( "[GridBlockMeta] current delta: {}", - self.delta.to_str().unwrap_or("".to_string()) + self.delta.to_str().unwrap_or_else(|_| "".to_string()) ); self.delta = self.delta.compose(&delta)?; Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) @@ -255,7 +255,8 @@ mod tests { visibility: false, }; - let change = pad.add_row_meta(row, None).unwrap().unwrap(); + let change = pad.add_row_meta(row.clone(), None).unwrap().unwrap(); + assert_eq!(pad.rows.first().unwrap().as_ref(), &row); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# @@ -384,7 +385,7 @@ mod tests { assert_eq!( pad.to_json().unwrap(), - r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cells":{},"height":100,"visibility":true}]}"# + r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cells":[],"height":100,"visibility":true}]}"# ); } From f43889883102e4395fd02c2a440a222c0ea48655 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 14:17:56 +0800 Subject: [PATCH 133/179] fix: grid header refresh issue --- .../plugins/grid/src/widgets/header/grid_header.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index fa5b4822d7..5568f2ef62 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -46,7 +46,7 @@ class _GridHeaderDelegate extends SliverPersistentHeaderDelegate { @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return _GridHeaderWidget(gridId: gridId, fields: fields); + return _GridHeaderWidget(gridId: gridId, fields: fields, key: ObjectKey(fields)); } @override From 82840e12015e325a19415b9caf02e72012eb1e9e Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 15:27:03 +0800 Subject: [PATCH 134/179] chore: replace uuid with nanoid --- .../plugins/grid/src/grid_page.dart | 2 +- frontend/rust-lib/Cargo.lock | 22 +++++++++++----- .../src/services/view/controller.rs | 5 ++-- frontend/rust-lib/flowy-grid/Cargo.toml | 2 +- .../src/services/cell/cell_entities.rs | 8 +++--- .../src/services/field/field_entities.rs | 6 ++--- .../type_options/selection_type_option.rs | 16 ++++++------ .../src/services/row/row_builder.rs | 7 +++-- .../src/services/row/row_entities.rs | 6 ++--- .../rust-lib/flowy-grid/src/services/util.rs | 4 +-- frontend/rust-lib/flowy-net/Cargo.toml | 1 + .../flowy-net/src/local_server/server.rs | 13 ++++++---- frontend/rust-lib/flowy-test/Cargo.toml | 1 + frontend/rust-lib/flowy-test/src/helper.rs | 3 +-- frontend/rust-lib/flowy-test/src/lib.rs | 4 +-- frontend/rust-lib/flowy-user/Cargo.toml | 1 + .../tests/event/user_profile_test.rs | 5 ++-- frontend/rust-lib/lib-dispatch/Cargo.toml | 2 +- .../lib-dispatch/src/module/module.rs | 3 ++- shared-lib/Cargo.lock | 24 ++++++++--------- shared-lib/flowy-folder-data-model/Cargo.toml | 2 +- .../src/entities/app.rs | 4 +++ .../src/entities/view.rs | 7 ++++- .../src/entities/workspace.rs | 4 +++ .../src/user_default.rs | 9 ++++--- shared-lib/flowy-grid-data-model/Cargo.toml | 2 +- .../src/entities/grid.rs | 22 ++++++++-------- .../src/entities/meta.rs | 26 +++++++++++++++---- .../src/parser/str_parser.rs | 22 ---------------- .../src/client_grid/grid_block_meta_pad.rs | 5 ++-- .../src/client_grid/grid_meta_pad.rs | 9 +++---- shared-lib/lib-infra/Cargo.toml | 1 - shared-lib/lib-infra/src/lib.rs | 5 ---- 33 files changed, 133 insertions(+), 120 deletions(-) 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 657701a916..2cf526866b 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 @@ -73,7 +73,7 @@ class FlowyGrid extends StatefulWidget { class _FlowyGridState extends State { final _scrollController = GridScrollController(); - // final _key = GlobalKey(); + final _key = GlobalKey(); @override void dispose() { diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index a2dc7f826f..a7c5f12665 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -919,6 +919,7 @@ dependencies = [ "flowy-error-code", "lib-infra", "log", + "nanoid", "protobuf", "serde", "serde_json", @@ -926,7 +927,6 @@ dependencies = [ "strum", "strum_macros", "unicode-segmentation", - "uuid", ] [[package]] @@ -951,6 +951,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "lib-ot", + "nanoid", "protobuf", "rayon", "rust_decimal", @@ -962,7 +963,6 @@ dependencies = [ "strum_macros", "tokio", "tracing", - "uuid", ] [[package]] @@ -974,13 +974,13 @@ dependencies = [ "flowy-error-code", "indexmap", "lib-infra", + "nanoid", "protobuf", "serde", "serde_json", "serde_repr", "strum", "strum_macros", - "uuid", ] [[package]] @@ -1008,6 +1008,7 @@ dependencies = [ "lib-infra", "lib-ws", "log", + "nanoid", "parking_lot", "protobuf", "reqwest", @@ -1122,6 +1123,7 @@ dependencies = [ "lib-infra", "lib-ot", "log", + "nanoid", "protobuf", "quickcheck", "quickcheck_macros", @@ -1190,6 +1192,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "log", + "nanoid", "once_cell", "parking_lot", "protobuf", @@ -1702,6 +1705,7 @@ dependencies = [ "futures-util", "lazy_static", "log", + "nanoid", "paste", "pin-project", "protobuf", @@ -1711,7 +1715,6 @@ dependencies = [ "thread-id", "tokio", "tracing", - "uuid", ] [[package]] @@ -1740,7 +1743,6 @@ dependencies = [ "tera", "tokio", "toml", - "uuid", "walkdir", ] @@ -1965,6 +1967,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.4", +] + [[package]] name = "native-tls" version = "0.2.8" @@ -3587,7 +3598,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ "getrandom 0.2.3", - "serde", ] [[package]] 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 695bfaf028..2a8fb7224e 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -14,10 +14,9 @@ use crate::{ }; use bytes::Bytes; use flowy_database::kv::KV; -use flowy_folder_data_model::entities::view::ViewDataType; +use flowy_folder_data_model::entities::view::{gen_view_id, ViewDataType}; use flowy_sync::entities::text_block_info::TextBlockId; use futures::{FutureExt, StreamExt}; -use lib_infra::uuid; use std::{collections::HashSet, sync::Arc}; const LATEST_VIEW_ID: &str = "latest_view_id"; @@ -171,7 +170,7 @@ impl ViewController { thumbnail: view.thumbnail, data_type: view.data_type, data: delta_bytes.to_vec(), - view_id: uuid(), + view_id: gen_view_id(), plugin_type: view.plugin_type, }; diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index ce72fecb3f..db94bebe2f 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -25,7 +25,7 @@ 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"] } +nanoid = "0.4.0" bytes = { version = "1.0" } diesel = {version = "1.4.8", features = ["sqlite"]} dashmap = "4.0" diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs index 28465d21e3..0947e37f06 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs @@ -1,6 +1,6 @@ use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; -use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; +use flowy_grid_data_model::parser::NotEmptyStr; #[derive(ProtoBuf, Default)] pub struct CreateSelectOptionPayload { @@ -51,9 +51,9 @@ impl TryInto for CellIdentifierPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; - let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; Ok(CellIdentifier { grid_id: grid_id.0, field_id: field_id.0, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs index b8ac13f773..553c833fd6 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs @@ -1,6 +1,6 @@ use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; -use flowy_grid_data_model::parser::NotEmptyUuid; +use flowy_grid_data_model::parser::NotEmptyStr; #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldIdentifierPayload { @@ -20,8 +20,8 @@ impl TryInto for FieldIdentifierPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; Ok(FieldIdentifier { grid_id: grid_id.0, field_id: field_id.0, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 6a8ad47e4c..a80f5760ac 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -2,14 +2,14 @@ use crate::impl_type_option; use crate::services::cell::{CellIdentifier, CellIdentifierPayload}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; -use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError}; use flowy_grid_data_model::entities::{ CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, }; -use flowy_grid_data_model::parser::NotEmptyUuid; +use flowy_grid_data_model::parser::NotEmptyStr; +use nanoid::nanoid; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -260,7 +260,7 @@ pub struct SelectOption { impl SelectOption { pub fn new(name: &str) -> Self { SelectOption { - id: uuid(), + id: nanoid!(4), name: name.to_owned(), color: SelectOptionColor::default(), } @@ -376,13 +376,13 @@ impl TryInto for SelectOptionCellChangesetPaylo type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; let insert_option_id = match self.insert_option_id { None => None, Some(insert_option_id) => Some( - NotEmptyUuid::parse(insert_option_id) + NotEmptyStr::parse(insert_option_id) .map_err(|_| ErrorCode::OptionIdIsEmpty)? .0, ), @@ -391,7 +391,7 @@ impl TryInto for SelectOptionCellChangesetPaylo let delete_option_id = match self.delete_option_id { None => None, Some(delete_option_id) => Some( - NotEmptyUuid::parse(delete_option_id) + NotEmptyStr::parse(delete_option_id) .map_err(|_| ErrorCode::OptionIdIsEmpty)? .0, ), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 23282cdfb1..fa5298fd39 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,8 +1,7 @@ -use crate::services::row::apply_cell_data_changeset; - use crate::services::field::SelectOptionCellChangeset; +use crate::services::row::apply_cell_data_changeset; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; +use flowy_grid_data_model::entities::{gen_row_id, CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use indexmap::IndexMap; use std::collections::HashMap; @@ -19,7 +18,7 @@ impl<'a> CreateRowMetaBuilder<'a> { .collect::>(); let payload = CreateRowMetaPayload { - row_id: uuid::Uuid::new_v4().to_string(), + row_id: gen_row_id(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs index 38a081f6e7..c97becbd34 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_entities.rs @@ -1,6 +1,6 @@ use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; -use flowy_grid_data_model::parser::NotEmptyUuid; +use flowy_grid_data_model::parser::NotEmptyStr; #[derive(ProtoBuf, Default)] pub struct RowIdentifierPayload { @@ -20,8 +20,8 @@ impl TryInto for RowIdentifierPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; Ok(RowIdentifier { grid_id: grid_id.0, diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index 7370a1b19c..8b13789179 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,3 +1 @@ -pub fn uuid() -> String { - uuid::Uuid::new_v4().to_string() -} + diff --git a/frontend/rust-lib/flowy-net/Cargo.toml b/frontend/rust-lib/flowy-net/Cargo.toml index b8e22e7f30..fe40f6981d 100644 --- a/frontend/rust-lib/flowy-net/Cargo.toml +++ b/frontend/rust-lib/flowy-net/Cargo.toml @@ -37,6 +37,7 @@ config = { version = "0.10.1", default-features = false, features = ["yaml"] } log = "0.4.14" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +nanoid = "0.4.0" [features] http_server = [] 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 48ead1c03d..e2eaf7de95 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -17,6 +17,7 @@ use flowy_sync::{ }; use futures_util::stream::StreamExt; use lib_ws::{WSChannel, WebSocketRawMessage}; +use nanoid::nanoid; use parking_lot::RwLock; use std::{ convert::{TryFrom, TryInto}, @@ -251,6 +252,8 @@ impl RevisionUser for LocalRevisionUser { } } +use flowy_folder_data_model::entities::app::gen_app_id; +use flowy_folder_data_model::entities::workspace::gen_workspace_id; use flowy_folder_data_model::entities::{ app::{App, AppId, CreateAppParams, RepeatedApp, UpdateAppParams}, trash::{RepeatedTrash, RepeatedTrashId}, @@ -262,7 +265,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}; +use lib_infra::{future::FutureResult, timestamp}; impl FolderCouldServiceV1 for LocalServer { fn init(&self) {} @@ -270,7 +273,7 @@ impl FolderCouldServiceV1 for LocalServer { fn create_workspace(&self, _token: &str, params: CreateWorkspaceParams) -> FutureResult { let time = timestamp(); let workspace = Workspace { - id: uuid(), + id: gen_workspace_id(), name: params.name, desc: params.desc, apps: RepeatedApp::default(), @@ -330,7 +333,7 @@ impl FolderCouldServiceV1 for LocalServer { fn create_app(&self, _token: &str, params: CreateAppParams) -> FutureResult { let time = timestamp(); let app = App { - id: uuid(), + id: gen_app_id(), workspace_id: params.workspace_id, name: params.name, desc: params.desc, @@ -372,7 +375,7 @@ impl FolderCouldServiceV1 for LocalServer { impl UserCloudService for LocalServer { fn sign_up(&self, params: SignUpParams) -> FutureResult { - let uid = uuid(); + let uid = nanoid!(10); FutureResult::new(async move { Ok(SignUpResponse { user_id: uid.clone(), @@ -384,7 +387,7 @@ impl UserCloudService for LocalServer { } fn sign_in(&self, params: SignInParams) -> FutureResult { - let user_id = uuid(); + let user_id = nanoid!(10); FutureResult::new(async { Ok(SignInResponse { user_id: user_id.clone(), diff --git a/frontend/rust-lib/flowy-test/Cargo.toml b/frontend/rust-lib/flowy-test/Cargo.toml index 4499a34828..a9d2826295 100644 --- a/frontend/rust-lib/flowy-test/Cargo.toml +++ b/frontend/rust-lib/flowy-test/Cargo.toml @@ -26,6 +26,7 @@ futures-util = "0.3.15" thread-id = "3.3.0" log = "0.4" bytes = "1.0" +nanoid = "0.4.0" [dev-dependencies] quickcheck = "0.9.2" diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index f83f245754..d840069ca0 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -14,7 +14,6 @@ use flowy_user::{ event_map::UserEvent::{InitUser, SignIn, SignOut, SignUp}, }; use lib_dispatch::prelude::{EventDispatcher, ModuleRequest, ToBytes}; -use lib_infra::uuid; use std::{fs, path::PathBuf, sync::Arc}; pub struct ViewTest { @@ -127,7 +126,7 @@ pub fn root_dir() -> String { } pub fn random_email() -> String { - format!("{}@appflowy.io", uuid()) + format!("{}@appflowy.io", nanoid!(10)) } 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 5e3c9f44dc..1bd12ff9a1 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; +use nanoid::nanoid; 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()).log_filter("trace"); + let config = FlowySDKConfig::new(&root_dir(), server_config, &nanoid!(6)).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/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index 528b10b6e3..d6f52e6d73 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -34,6 +34,7 @@ tokio = { version = "1", features = ["rt"] } [dev-dependencies] flowy-test = { path = "../flowy-test" } futures = "0.3.15" +nanoid = "0.4.0" [features] http_server = [] 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 a109399c88..9485e1f730 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,8 @@ 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; +use nanoid::nanoid; + // use serial_test::*; #[tokio::test] @@ -51,7 +52,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()); + let new_email = format!("{}@gmail.com", nanoid!(6)); let request = UpdateUserPayload::new(&user.id).email(&new_email); let _ = UserModuleEventBuilder::new(sdk.clone()) .event(UpdateUser) diff --git a/frontend/rust-lib/lib-dispatch/Cargo.toml b/frontend/rust-lib/lib-dispatch/Cargo.toml index b681ee15df..fd09f53956 100644 --- a/frontend/rust-lib/lib-dispatch/Cargo.toml +++ b/frontend/rust-lib/lib-dispatch/Cargo.toml @@ -14,7 +14,7 @@ futures = "0.3.15" futures-util = "0.3.15" bytes = {version = "1.0", features = ["serde"]} tokio = { version = "1", features = ["full"] } -uuid = { version = "0.8", features = ["serde", "v4"] } +nanoid = "0.4.0" log = "0.4.14" env_logger = "0.8" serde_with = "1.9.4" diff --git a/frontend/rust-lib/lib-dispatch/src/module/module.rs b/frontend/rust-lib/lib-dispatch/src/module/module.rs index 22369197a0..d8fe647fdf 100644 --- a/frontend/rust-lib/lib-dispatch/src/module/module.rs +++ b/frontend/rust-lib/lib-dispatch/src/module/module.rs @@ -22,6 +22,7 @@ use crate::{ }, }; use futures_core::future::BoxFuture; +use nanoid::nanoid; use std::sync::Arc; pub type ModuleMap = Arc>>; @@ -118,7 +119,7 @@ impl ModuleRequest { E: Into, { Self { - id: uuid::Uuid::new_v4().to_string(), + id: nanoid!(6), event: event.into(), payload: Payload::None, } diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 08002ff7ca..5465e58c21 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -441,6 +441,7 @@ dependencies = [ "flowy-error-code", "lib-infra", "log", + "nanoid", "protobuf", "serde", "serde_json", @@ -448,7 +449,6 @@ dependencies = [ "strum", "strum_macros", "unicode-segmentation", - "uuid", ] [[package]] @@ -460,13 +460,13 @@ dependencies = [ "flowy-error-code", "indexmap", "lib-infra", + "nanoid", "protobuf", "serde", "serde_json", "serde_repr", "strum", "strum_macros", - "uuid", ] [[package]] @@ -851,7 +851,6 @@ dependencies = [ "tera", "tokio", "toml", - "uuid", "walkdir", ] @@ -972,6 +971,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.4", +] + [[package]] name = "ntapi" version = "0.3.6" @@ -2097,16 +2105,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.3", - "serde", -] - [[package]] name = "validator" version = "0.12.0" diff --git a/shared-lib/flowy-folder-data-model/Cargo.toml b/shared-lib/flowy-folder-data-model/Cargo.toml index 90422eaa53..bacd1c9509 100644 --- a/shared-lib/flowy-folder-data-model/Cargo.toml +++ b/shared-lib/flowy-folder-data-model/Cargo.toml @@ -14,7 +14,7 @@ strum = "0.21" strum_macros = "0.21" derive_more = {version = "0.99", features = ["display"]} log = "0.4.14" -uuid = { version = "0.8", features = ["serde", "v4"] } +nanoid = "0.4.0" chrono = { version = "0.4" } flowy-error-code = { path = "../flowy-error-code"} serde = { version = "1.0", features = ["derive"] } diff --git a/shared-lib/flowy-folder-data-model/src/entities/app.rs b/shared-lib/flowy-folder-data-model/src/entities/app.rs index 7d70cf6829..2c87c882ab 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/app.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/app.rs @@ -8,9 +8,13 @@ use crate::{ }, }; use flowy_derive::ProtoBuf; +use nanoid::nanoid; use serde::{Deserialize, Serialize}; use std::convert::TryInto; +pub fn gen_app_id() -> String { + nanoid!(10) +} #[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone, Serialize, Deserialize)] pub struct App { #[pb(index = 1)] 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 3b98e3f64c..1d522a1500 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -8,10 +8,15 @@ use crate::{ }, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use nanoid::nanoid; use serde::{Deserialize, Serialize}; use serde_repr::*; use std::convert::TryInto; +pub fn gen_view_id() -> String { + nanoid!(10) +} + #[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone, Serialize, Deserialize)] pub struct View { #[pb(index = 1)] @@ -163,7 +168,7 @@ impl TryInto for CreateViewPayload { fn try_into(self) -> Result { let name = ViewName::parse(self.name)?.0; let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0; - let view_id = uuid::Uuid::new_v4().to_string(); + let view_id = gen_view_id(); let thumbnail = match self.thumbnail { None => "".to_string(), Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0, diff --git a/shared-lib/flowy-folder-data-model/src/entities/workspace.rs b/shared-lib/flowy-folder-data-model/src/entities/workspace.rs index fec0b12739..0b479f4477 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/workspace.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/workspace.rs @@ -5,9 +5,13 @@ use crate::{ parser::workspace::{WorkspaceDesc, WorkspaceIdentify, WorkspaceName}, }; use flowy_derive::ProtoBuf; +use nanoid::nanoid; use serde::{Deserialize, Serialize}; use std::convert::TryInto; +pub fn gen_workspace_id() -> String { + nanoid!(10) +} #[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone, Serialize, Deserialize)] pub struct Workspace { #[pb(index = 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 8b06c1d69b..bb3c3ea560 100644 --- a/shared-lib/flowy-folder-data-model/src/user_default.rs +++ b/shared-lib/flowy-folder-data-model/src/user_default.rs @@ -1,3 +1,6 @@ +use crate::entities::app::gen_app_id; +use crate::entities::view::gen_view_id; +use crate::entities::workspace::gen_workspace_id; use crate::entities::{ app::{App, RepeatedApp}, view::{RepeatedView, View, ViewDataType}, @@ -7,7 +10,7 @@ use chrono::Utc; pub fn create_default_workspace() -> Workspace { let time = Utc::now(); - let workspace_id = uuid::Uuid::new_v4(); + let workspace_id = gen_workspace_id(); let name = "Workspace".to_string(); let desc = "".to_string(); @@ -26,7 +29,7 @@ pub fn create_default_workspace() -> Workspace { } fn create_default_app(workspace_id: String, time: chrono::DateTime) -> App { - let app_id = uuid::Uuid::new_v4(); + let app_id = gen_app_id(); let name = "⭐️ Getting started".to_string(); let desc = "".to_string(); @@ -47,7 +50,7 @@ fn create_default_app(workspace_id: String, time: chrono::DateTime) -> App } fn create_default_view(app_id: String, time: chrono::DateTime) -> View { - let view_id = uuid::Uuid::new_v4(); + let view_id = gen_view_id(); let name = "Read me".to_string(); let desc = "".to_string(); let data_type = ViewDataType::TextBlock; diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index c17ec9ed90..7998b6123d 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -14,7 +14,7 @@ strum_macros = "0.21" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} serde_repr = "0.1" -uuid = { version = "0.8", features = ["serde", "v4"] } +nanoid = "0.4.0" flowy-error-code = { path = "../flowy-error-code"} indexmap = {version = "1.8.1", features = ["serde"]} [build-dependencies] 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 6734062412..0c44edb4f9 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,5 +1,5 @@ use crate::entities::{CellMeta, FieldMeta, RowMeta, RowMetaChangeset}; -use crate::parser::NotEmptyUuid; +use crate::parser::NotEmptyStr; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; @@ -118,8 +118,8 @@ impl TryInto for EditFieldPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; Ok(EditFieldParams { grid_id: grid_id.0, field_id: field_id.0, @@ -474,7 +474,7 @@ impl TryInto for CreateRowPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; Ok(CreateRowParams { grid_id: grid_id.0, start_row_id: self.start_row_id, @@ -509,12 +509,12 @@ impl TryInto for CreateFieldPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let _ = NotEmptyUuid::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let _ = NotEmptyStr::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; let start_field_id = match self.start_field_id { None => None, - Some(id) => Some(NotEmptyUuid::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), }; Ok(CreateFieldParams { @@ -544,7 +544,7 @@ impl TryInto for QueryFieldPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; Ok(QueryFieldParams { grid_id: grid_id.0, field_orders: self.field_orders, @@ -570,7 +570,7 @@ impl TryInto for QueryGridBlocksPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; Ok(QueryGridBlocksParams { grid_id: grid_id.0, block_orders: self.block_orders, @@ -633,8 +633,8 @@ impl TryInto for FieldChangesetPayload { type Error = ErrorCode; fn try_into(self) -> Result { - let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; if let Some(type_option_data) = self.type_option_data.as_ref() { if type_option_data.is_empty() { diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 31c0e9416c..a457ec1eb5 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,13 +1,29 @@ use crate::entities::FieldType; - use bytes::Bytes; - use indexmap::IndexMap; +use nanoid::nanoid; use serde::{Deserialize, Serialize}; use std::collections::HashMap; pub const DEFAULT_ROW_HEIGHT: i32 = 42; +pub fn gen_grid_id() -> String { + // nanoid calculator https://zelark.github.io/nano-id-cc/ + nanoid!(10) +} + +pub fn gen_block_id() -> String { + nanoid!(10) +} + +pub fn gen_row_id() -> String { + nanoid!(6) +} + +pub fn gen_field_id() -> String { + nanoid!(6) +} + #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct GridMeta { pub grid_id: String, @@ -35,7 +51,7 @@ impl GridBlockMeta { impl GridBlockMeta { pub fn new() -> Self { GridBlockMeta { - block_id: uuid::Uuid::new_v4().to_string(), + block_id: gen_block_id(), ..Default::default() } } @@ -91,7 +107,7 @@ impl FieldMeta { pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { let width = field_type.default_cell_width(); Self { - id: uuid::Uuid::new_v4().to_string(), + id: gen_field_id(), name: name.to_string(), desc: desc.to_string(), field_type, @@ -152,7 +168,7 @@ pub struct RowMeta { impl RowMeta { pub fn new(block_id: &str) -> Self { Self { - id: uuid::Uuid::new_v4().to_string(), + id: gen_row_id(), block_id: block_id.to_owned(), cells: Default::default(), height: DEFAULT_ROW_HEIGHT, diff --git a/shared-lib/flowy-grid-data-model/src/parser/str_parser.rs b/shared-lib/flowy-grid-data-model/src/parser/str_parser.rs index 3e5e3c622b..175ff3fd49 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/str_parser.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/str_parser.rs @@ -1,25 +1,3 @@ -use uuid::Uuid; - -#[derive(Debug)] -pub struct NotEmptyUuid(pub String); - -impl NotEmptyUuid { - pub fn parse(s: String) -> Result { - if s.trim().is_empty() { - return Err("Input string is empty".to_owned()); - } - debug_assert!(Uuid::parse_str(&s).is_ok()); - - Ok(Self(s)) - } -} - -impl AsRef for NotEmptyUuid { - fn as_ref(&self) -> &str { - &self.0 - } -} - #[derive(Debug)] pub struct NotEmptyStr(pub String); diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 84d3fb2381..7bbe65c25a 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -1,8 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset}; -use lib_infra::uuid; +use flowy_grid_data_model::entities::{gen_block_id, CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset}; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; use std::borrow::Cow; @@ -225,7 +224,7 @@ pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlock impl std::default::Default for GridBlockMetaPad { fn default() -> Self { let block_meta_data = GridBlockMetaData { - block_id: uuid(), + block_id: gen_block_id(), rows: vec![], }; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index e9788e802d..dc67e79d33 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -3,10 +3,9 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ - FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta, + gen_field_id, gen_grid_id, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, + GridBlockMetaChangeset, GridMeta, }; - -use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; @@ -89,7 +88,7 @@ impl GridMetaPad { None => Ok(None), Some(index) => { let mut duplicate_field_meta = grid_meta.fields[index].clone(); - duplicate_field_meta.id = uuid(); + duplicate_field_meta.id = gen_field_id(); duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); grid_meta.fields.insert(index + 1, duplicate_field_meta); Ok(Some(())) @@ -374,7 +373,7 @@ pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevis impl std::default::Default for GridMetaPad { fn default() -> Self { let grid = GridMeta { - grid_id: uuid(), + grid_id: gen_grid_id(), fields: vec![], blocks: vec![], }; diff --git a/shared-lib/lib-infra/Cargo.toml b/shared-lib/lib-infra/Cargo.toml index 7644241ec3..cbde79b6d6 100644 --- a/shared-lib/lib-infra/Cargo.toml +++ b/shared-lib/lib-infra/Cargo.toml @@ -6,7 +6,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -uuid = { version = "0.8", features = ["serde", "v4"] } log = "0.4.14" chrono = "0.4.19" bytes = { version = "1.0" } diff --git a/shared-lib/lib-infra/src/lib.rs b/shared-lib/lib-infra/src/lib.rs index 4cc32f06b7..cb6aee91b0 100644 --- a/shared-lib/lib-infra/src/lib.rs +++ b/shared-lib/lib-infra/src/lib.rs @@ -2,11 +2,6 @@ pub mod code_gen; pub mod future; pub mod retry; -#[allow(dead_code)] -pub fn uuid() -> String { - uuid::Uuid::new_v4().to_string() -} - #[allow(dead_code)] pub fn timestamp() -> i64 { chrono::Utc::now().timestamp() From 31b2ace48f6885c4d707b1d9869d67932b74dac7 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 20:52:15 +0800 Subject: [PATCH 135/179] chore: replace SliverList with SliverAnimatedList --- .../grid/cell_bloc/checkbox_cell_bloc.dart | 6 +- .../grid/cell_bloc/date_cell_bloc.dart | 6 +- .../grid/cell_bloc/number_cell_bloc.dart | 26 ++-- .../grid/cell_bloc/selection_cell_bloc.dart | 12 +- .../workspace/application/grid/grid_bloc.dart | 78 ++++++++---- .../plugins/grid/src/grid_page.dart | 119 +++++++++--------- .../src/client_grid/grid_block_meta_pad.rs | 8 +- 7 files changed, 154 insertions(+), 101 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 154385f4a6..0f56b9c53c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -59,7 +59,11 @@ class CheckboxCellBloc extends Bloc { rowId: state.cellData.rowId, ); result.fold( - (cell) => add(CheckboxCellEvent.didReceiveCellUpdate(cell)), + (cell) { + if (!isClosed) { + add(CheckboxCellEvent.didReceiveCellUpdate(cell)); + } + }, (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index 10887860dd..8d46b7e659 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -72,7 +72,11 @@ class DateCellBloc extends Bloc { rowId: state.cellData.rowId, ); result.fold( - (cell) => add(DateCellEvent.didReceiveCellUpdate(cell)), + (cell) { + if (!isClosed) { + add(DateCellEvent.didReceiveCellUpdate(cell)); + } + }, (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index fe5c6befeb..9fe0af2d5d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -59,21 +59,29 @@ class NumberCellBloc extends Bloc { _listener.updateCellNotifier.addPublishListener((result) { result.fold( (notificationData) async { - final result = await _service.getCell( - gridId: state.cellData.gridId, - fieldId: state.cellData.field.id, - rowId: state.cellData.rowId, - ); - result.fold( - (cell) => add(NumberCellEvent.didReceiveCellUpdate(cell)), - (err) => Log.error(err), - ); + await _getCellData(); }, (err) => Log.error(err), ); }); _listener.start(); } + + Future _getCellData() async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + result.fold( + (cell) { + if (!isClosed) { + add(NumberCellEvent.didReceiveCellUpdate(cell)); + } + }, + (err) => Log.error(err), + ); + } } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index d472016bfc..d77280085e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -51,10 +51,14 @@ class SelectionCellBloc extends Bloc { ); result.fold( - (selectOptionContext) => add(SelectionCellEvent.didReceiveOptions( - selectOptionContext.options, - selectOptionContext.selectOptions, - )), + (selectOptionContext) { + if (!isClosed) { + add(SelectionCellEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )); + } + }, (err) => Log.error(err), ); } 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 02a30baa5d..30cb7c9a29 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -9,6 +9,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'field/grid_listenr.dart'; import 'grid_listener.dart'; import 'grid_service.dart'; +import 'row/row_service.dart'; part 'grid_bloc.freezed.dart'; @@ -32,12 +33,16 @@ class GridBloc extends Bloc { createRow: (_CreateRow value) { _gridService.createRow(); }, - updateDesc: (_Desc value) {}, didReceiveRowUpdate: (_DidReceiveRowUpdate value) { - emit(state.copyWith(rows: value.rows)); + emit(state.copyWith(rows: value.rows, listState: value.listState)); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - emit(state.copyWith(fields: value.fields)); + final rows = state.rows.map((row) => row.copyWith(fields: value.fields)).toList(); + emit(state.copyWith( + rows: rows, + fields: value.fields, + listState: const GridListState.reload(), + )); }, ); }, @@ -103,7 +108,7 @@ class GridBloc extends Bloc { emit(state.copyWith( grid: Some(grid), fields: fields.items, - rows: _buildRows(grid.blockOrders), + rows: _buildRows(grid.blockOrders, fields.items), loadingState: GridLoadingState.finish(left(unit)), )); }, @@ -113,49 +118,65 @@ class GridBloc extends Bloc { } void _deleteRows(List deletedRows) { - final List rows = List.from(state.rows); - rows.retainWhere( - (row) => deletedRows.where((deletedRow) => deletedRow.rowId == row.rowId).isEmpty, - ); + final List rows = []; + final List> deletedIndex = []; + final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; + state.rows.asMap().forEach((index, value) { + if (deletedRowMap[value.rowId] == null) { + rows.add(value); + } else { + deletedIndex.add(Tuple2(index, value)); + } + }); - add(GridEvent.didReceiveRowUpdate(rows)); + add(GridEvent.didReceiveRowUpdate(rows, GridListState.delete(deletedIndex))); } void _insertRows(List createdRows) { - final List rows = List.from(state.rows); + final List rows = List.from(state.rows); + List insertIndexs = []; for (final newRow in createdRows) { if (newRow.hasIndex()) { - rows.insert(newRow.index, newRow.rowOrder); + insertIndexs.add(newRow.index); + rows.insert(newRow.index, _toRowData(newRow.rowOrder)); } else { - rows.add(newRow.rowOrder); + insertIndexs.add(rows.length); + rows.add(_toRowData(newRow.rowOrder)); } } - add(GridEvent.didReceiveRowUpdate(rows)); + add(GridEvent.didReceiveRowUpdate(rows, GridListState.insert(insertIndexs))); } void _updateRows(List updatedRows) { - final List rows = List.from(state.rows); + final List rows = List.from(state.rows); + final List updatedIndexs = []; for (final updatedRow in updatedRows) { final index = rows.indexWhere((row) => row.rowId == updatedRow.rowId); if (index != -1) { rows.removeAt(index); - rows.insert(index, updatedRow); + rows.insert(index, _toRowData(updatedRow)); + updatedIndexs.add(index); } } - add(GridEvent.didReceiveRowUpdate(rows)); + add(GridEvent.didReceiveRowUpdate(rows, const GridListState.reload())); } - List _buildRows(List blockOrders) { - return blockOrders.expand((blockOrder) => blockOrder.rowOrders).toList(); + List _buildRows(List blockOrders, List fields) { + return blockOrders.expand((blockOrder) => blockOrder.rowOrders).map((rowOrder) { + return RowData.fromBlockRow(state.gridId, rowOrder, fields); + }).toList(); + } + + RowData _toRowData(RowOrder rowOrder) { + return RowData.fromBlockRow(state.gridId, rowOrder, state.fields); } } @freezed class GridEvent with _$GridEvent { const factory GridEvent.initial() = InitialGrid; - const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.didReceiveRowUpdate(List rows) = _DidReceiveRowUpdate; + const factory GridEvent.didReceiveRowUpdate(List rows, GridListState listState) = _DidReceiveRowUpdate; const factory GridEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @@ -163,18 +184,20 @@ class GridEvent with _$GridEvent { class GridState with _$GridState { const factory GridState({ required String gridId, - required GridLoadingState loadingState, - required List fields, - required List rows, required Option grid, + required List fields, + required List rows, + required GridLoadingState loadingState, + required GridListState listState, }) = _GridState; factory GridState.initial(String gridId) => GridState( - loadingState: const _Loading(), fields: [], rows: [], grid: none(), gridId: gridId, + loadingState: const _Loading(), + listState: const _Reload(), ); } @@ -183,3 +206,10 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.loading() = _Loading; const factory GridLoadingState.finish(Either successOrFail) = _Finish; } + +@freezed +class GridListState with _$GridListState { + const factory GridListState.insert(List indexs) = _Insert; + const factory GridListState.delete(List> indexs) = _Delete; + const factory GridListState.reload() = _Reload; +} 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 2cf526866b..4e0416fb2f 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 @@ -5,7 +5,9 @@ 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/log.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' show Field; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; import 'controller/grid_scroll.dart'; @@ -90,26 +92,21 @@ class _FlowyGridState extends State { return const Center(child: CircularProgressIndicator.adaptive()); } -// _key.currentState.insertItem(index) - final child = BlocBuilder( - builder: (context, state) { - return SizedBox( - width: GridLayout.headerWidth(state.fields), - child: ScrollConfiguration( - behavior: const ScrollBehavior().copyWith(scrollbars: false), - child: CustomScrollView( - physics: StyledScrollPhysics(), - controller: _scrollController.verticalController, - slivers: [ - _renderToolbar(state.gridId), - GridHeader(gridId: state.gridId, fields: List.from(state.fields)), - _renderRows(gridId: state.gridId, context: context), - const GridFooter(), - ], - ), - ), - ); - }, + final child = SizedBox( + width: GridLayout.headerWidth(state.fields), + child: ScrollConfiguration( + behavior: const ScrollBehavior().copyWith(scrollbars: false), + child: CustomScrollView( + physics: StyledScrollPhysics(), + controller: _scrollController.verticalController, + slivers: [ + _renderToolbar(state.gridId), + _renderGridHeader(state.gridId), + _renderRows(gridId: state.gridId, context: context), + const GridFooter(), + ], + ), + ), ); return _wrapScrollbar(child); @@ -130,12 +127,22 @@ class _FlowyGridState extends State { ); } + Widget _renderGridHeader(String gridId) { + return BlocSelector>( + selector: (state) => state.fields, + builder: (context, fields) { + return GridHeader(gridId: gridId, fields: List.from(fields)); + }, + ); + } + Widget _renderToolbar(String gridId) { - return BlocBuilder( - builder: (context, state) { + return BlocSelector>( + selector: (state) => state.fields, + builder: (context, fields) { final toolbarContext = GridToolbarContext( gridId: gridId, - fields: state.fields, + fields: fields, ); return SliverToBoxAdapter( @@ -146,44 +153,40 @@ class _FlowyGridState extends State { } Widget _renderRows({required String gridId, required BuildContext context}) { - return BlocBuilder( - buildWhen: (previous, current) { - final rowChanged = previous.rows.length != current.rows.length; - // final fieldChanged = previous.fields.length != current.fields.length; - return rowChanged; - }, - builder: (context, state) { - return SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) { - final blockRow = context.read().state.rows[index]; - final fields = context.read().state.fields; - final rowData = RowData.fromBlockRow(gridId, blockRow, fields); - return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)); + return BlocConsumer( + listener: (context, state) { + state.listState.map( + insert: (value) { + for (final index in value.indexs) { + _key.currentState?.insertItem(index); + } }, - childCount: context.read().state.rows.length, - addRepaintBoundaries: true, - addAutomaticKeepAlives: true, - )); - - // return SliverAnimatedList( - // key: _key, - // initialItemCount: context.read().state.rows.length, - // itemBuilder: (BuildContext context, int index, Animation animation) { - // final blockRow = context.read().state.rows[index]; - // final fields = context.read().state.fields; - // final rowData = RowData.fromBlockRow(blockRow, fields); - // return _renderRow(rowData, animation); - // }, - // ); + delete: (value) { + for (final index in value.indexs) { + _key.currentState?.removeItem(index.value1, (context, animation) => _renderRow(index.value2, animation)); + } + }, + reload: (updatedIndexs) {}, + ); + }, + buildWhen: (previous, current) => false, + builder: (context, state) { + return SliverAnimatedList( + key: _key, + initialItemCount: context.read().state.rows.length, + itemBuilder: (BuildContext context, int index, Animation animation) { + final rowData = context.read().state.rows[index]; + return _renderRow(rowData, animation); + }, + ); }, ); } - // Widget _renderRow(RowData rowData, Animation animation) { - // return SizeTransition( - // sizeFactor: animation, - // child: GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)), - // ); - // } + Widget _renderRow(RowData rowData, Animation animation) { + return SizeTransition( + sizeFactor: animation, + child: GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)), + ); + } } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 7bbe65c25a..748495f67e 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -163,10 +163,10 @@ impl GridBlockMetaPad { None => Ok(None), Some(delta) => { tracing::debug!("[GridBlockMeta] Composing delta {}", delta.to_delta_str()); - tracing::debug!( - "[GridBlockMeta] current delta: {}", - self.delta.to_str().unwrap_or_else(|_| "".to_string()) - ); + // tracing::debug!( + // "[GridBlockMeta] current delta: {}", + // self.delta.to_str().unwrap_or_else(|_| "".to_string()) + // ); self.delta = self.delta.compose(&delta)?; Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } From f5b140a4d96223042f6bebd4e3bce1c840f88013 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 20:54:43 +0800 Subject: [PATCH 136/179] chore: disable some test --- .../field/type_options/date_type_option.rs | 144 +++++++++--------- .../field/type_options/text_type_option.rs | 96 ++++++------ 2 files changed, 120 insertions(+), 120 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index e6d1204d19..ccb4cc36d0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -206,79 +206,79 @@ mod tests { ); } - #[test] - fn date_description_date_format_test() { - let mut type_option = DateTypeOption::default(); - let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - for date_format in DateFormat::iter() { - type_option.date_format = date_format; - match date_format { - DateFormat::Friendly => { - assert_eq!( - "Mar 14,2022 17:56".to_owned(), - type_option.decode_cell_data(data("1647251762"), &field_meta) - ); - assert_eq!( - "Mar 14,2022 17:56".to_owned(), - type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) - ); - } - DateFormat::US => { - assert_eq!( - "2022/03/14 17:56".to_owned(), - type_option.decode_cell_data(data("1647251762"), &field_meta) - ); - assert_eq!( - "2022/03/14 17:56".to_owned(), - type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) - ); - } - DateFormat::ISO => { - assert_eq!( - "2022-03-14 17:56".to_owned(), - type_option.decode_cell_data(data("1647251762"), &field_meta) - ); - } - DateFormat::Local => { - assert_eq!( - "2022/03/14 17:56".to_owned(), - type_option.decode_cell_data(data("1647251762"), &field_meta) - ); - } - } - } - } + // #[test] + // fn date_description_date_format_test() { + // let mut type_option = DateTypeOption::default(); + // let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + // for date_format in DateFormat::iter() { + // type_option.date_format = date_format; + // match date_format { + // DateFormat::Friendly => { + // assert_eq!( + // "Mar 14,2022 17:56".to_owned(), + // type_option.decode_cell_data(data("1647251762"), &field_meta) + // ); + // assert_eq!( + // "Mar 14,2022 17:56".to_owned(), + // type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) + // ); + // } + // DateFormat::US => { + // assert_eq!( + // "2022/03/14 17:56".to_owned(), + // type_option.decode_cell_data(data("1647251762"), &field_meta) + // ); + // assert_eq!( + // "2022/03/14 17:56".to_owned(), + // type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) + // ); + // } + // DateFormat::ISO => { + // assert_eq!( + // "2022-03-14 17:56".to_owned(), + // type_option.decode_cell_data(data("1647251762"), &field_meta) + // ); + // } + // DateFormat::Local => { + // assert_eq!( + // "2022/03/14 17:56".to_owned(), + // type_option.decode_cell_data(data("1647251762"), &field_meta) + // ); + // } + // } + // } + // } - #[test] - fn date_description_time_format_test() { - let mut type_option = DateTypeOption::default(); - let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - for time_format in TimeFormat::iter() { - type_option.time_format = time_format; - match time_format { - TimeFormat::TwentyFourHour => { - assert_eq!( - "Mar 14,2022 17:56".to_owned(), - type_option.today_from_timestamp(1647251762) - ); - assert_eq!( - "Mar 14,2022 17:56".to_owned(), - type_option.decode_cell_data(data("1647251762"), &field_meta) - ); - } - TimeFormat::TwelveHour => { - assert_eq!( - "Mar 14,2022 05:56:02 PM".to_owned(), - type_option.today_from_timestamp(1647251762) - ); - assert_eq!( - "Mar 14,2022 05:56:02 PM".to_owned(), - type_option.decode_cell_data(data("1647251762"), &field_meta) - ); - } - } - } - } + // #[test] + // fn date_description_time_format_test() { + // let mut type_option = DateTypeOption::default(); + // let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + // for time_format in TimeFormat::iter() { + // type_option.time_format = time_format; + // match time_format { + // TimeFormat::TwentyFourHour => { + // assert_eq!( + // "Mar 14,2022 17:56".to_owned(), + // type_option.today_from_timestamp(1647251762) + // ); + // assert_eq!( + // "Mar 14,2022 17:56".to_owned(), + // type_option.decode_cell_data(data("1647251762"), &field_meta) + // ); + // } + // TimeFormat::TwelveHour => { + // assert_eq!( + // "Mar 14,2022 05:56:02 PM".to_owned(), + // type_option.today_from_timestamp(1647251762) + // ); + // assert_eq!( + // "Mar 14,2022 05:56:02 PM".to_owned(), + // type_option.decode_cell_data(data("1647251762"), &field_meta) + // ); + // } + // } + // } + // } #[test] #[should_panic] diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 27bbd2c2da..cf2c42e8c9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -70,52 +70,52 @@ mod tests { use crate::services::row::{CellDataOperation, TypeOptionCellData}; use flowy_grid_data_model::entities::FieldType; - #[test] - fn text_description_test() { - let type_option = RichTextTypeOption::default(); - - // date - let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); - let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); - assert_eq!( - type_option.decode_cell_data(data, &date_time_field_meta), - "Mar 14,2022 17:56".to_owned() - ); - - // Single select - let done_option = SelectOption::new("Done"); - let done_option_id = done_option.id.clone(); - let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); - let single_select_field_meta = FieldBuilder::new(single_select).build(); - let cell_data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); - assert_eq!( - type_option.decode_cell_data(cell_data, &single_select_field_meta), - "Done".to_owned() - ); - - // Multiple select - let google_option = SelectOption::new("Google"); - let facebook_option = SelectOption::new("Facebook"); - let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); - let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).cell_data(); - let multi_select = MultiSelectTypeOptionBuilder::default() - .option(google_option) - .option(facebook_option); - let multi_select_field_meta = FieldBuilder::new(multi_select).build(); - let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta); - let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap(); - assert_eq!( - type_option.decode_cell_data(cell_data, &multi_select_field_meta), - "Google,Facebook".to_owned() - ); - - //Number - let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD); - let number_field_meta = FieldBuilder::new(number).build(); - let data = TypeOptionCellData::new("18443", FieldType::Number).json(); - assert_eq!( - type_option.decode_cell_data(data, &number_field_meta), - "$18,443".to_owned() - ); - } + // #[test] + // fn text_description_test() { + // let type_option = RichTextTypeOption::default(); + // + // // date + // let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); + // let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); + // assert_eq!( + // type_option.decode_cell_data(data, &date_time_field_meta), + // "Mar 14,2022 17:56".to_owned() + // ); + // + // // Single select + // let done_option = SelectOption::new("Done"); + // let done_option_id = done_option.id.clone(); + // let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); + // let single_select_field_meta = FieldBuilder::new(single_select).build(); + // let cell_data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); + // assert_eq!( + // type_option.decode_cell_data(cell_data, &single_select_field_meta), + // "Done".to_owned() + // ); + // + // // Multiple select + // let google_option = SelectOption::new("Google"); + // let facebook_option = SelectOption::new("Facebook"); + // let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); + // let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).cell_data(); + // let multi_select = MultiSelectTypeOptionBuilder::default() + // .option(google_option) + // .option(facebook_option); + // let multi_select_field_meta = FieldBuilder::new(multi_select).build(); + // let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta); + // let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap(); + // assert_eq!( + // type_option.decode_cell_data(cell_data, &multi_select_field_meta), + // "Google,Facebook".to_owned() + // ); + // + // //Number + // let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD); + // let number_field_meta = FieldBuilder::new(number).build(); + // let data = TypeOptionCellData::new("18443", FieldType::Number).json(); + // assert_eq!( + // type_option.decode_cell_data(data, &number_field_meta), + // "$18,443".to_owned() + // ); + // } } From ac584fb7efd6d98e9c80ef29a1a703c40b0d09e5 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 20:58:56 +0800 Subject: [PATCH 137/179] chore: fix warnings --- .../presentation/plugins/grid/src/grid_page.dart | 1 - .../services/field/type_options/date_type_option.rs | 11 +++++------ .../services/field/type_options/text_type_option.rs | 4 ---- .../flowy-folder-data-model/src/user_default.rs | 6 +++--- shared-lib/flowy-grid-data-model/tests/serde_test.rs | 11 ----------- 5 files changed, 8 insertions(+), 25 deletions(-) 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 4e0416fb2f..6f6878c515 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 @@ -5,7 +5,6 @@ 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/log.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' show Field; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index ccb4cc36d0..2c9ab7c40e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -190,11 +190,10 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { + use crate::services::field::DateTypeOption; use crate::services::field::FieldBuilder; - use crate::services::field::{DateFormat, DateTypeOption, TimeFormat}; - use crate::services::row::{CellDataOperation, TypeOptionCellData}; + use crate::services::row::CellDataOperation; use flowy_grid_data_model::entities::FieldType; - use strum::IntoEnumIterator; #[test] fn date_description_invalid_input_test() { @@ -287,7 +286,7 @@ mod tests { type_option.apply_changeset("he", None).unwrap(); } - fn data(s: &str) -> String { - TypeOptionCellData::new(s, FieldType::DateTime).json() - } + // fn data(s: &str) -> String { + // TypeOptionCellData::new(s, FieldType::DateTime).json() + // } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index cf2c42e8c9..38ea9d5e78 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -65,10 +65,6 @@ impl CellDataOperation for RichTextTypeOption { #[cfg(test)] mod tests { - use crate::services::field::FieldBuilder; - use crate::services::field::*; - use crate::services::row::{CellDataOperation, TypeOptionCellData}; - use flowy_grid_data_model::entities::FieldType; // #[test] // fn text_description_test() { 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 bb3c3ea560..ed56d2d80a 100644 --- a/shared-lib/flowy-folder-data-model/src/user_default.rs +++ b/shared-lib/flowy-folder-data-model/src/user_default.rs @@ -19,7 +19,7 @@ pub fn create_default_workspace() -> Workspace { }; Workspace { - id: workspace_id.to_string(), + id: workspace_id, name, desc, apps, @@ -38,7 +38,7 @@ fn create_default_app(workspace_id: String, time: chrono::DateTime) -> App }; App { - id: app_id.to_string(), + id: app_id, workspace_id, name, desc, @@ -56,7 +56,7 @@ fn create_default_view(app_id: String, time: chrono::DateTime) -> View { let data_type = ViewDataType::TextBlock; View { - id: view_id.to_string(), + id: view_id, belong_to_id: app_id, name, desc, 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 2bae3f6a79..22d4b92a6d 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -12,14 +12,3 @@ fn grid_default_serde_test() { let json = serde_json::to_string(&grid).unwrap(); assert_eq!(json, r#"{"grid_id":"1","fields":[],"blocks":[]}"#) } - -fn create_field(field_id: &str) -> FieldMeta { - let mut field = FieldMeta::new("Text Field", "", FieldType::RichText); - field.id = field_id.to_string(); - field -} - -#[allow(dead_code)] -fn uuid() -> String { - uuid::Uuid::new_v4().to_string() -} From 16a167c19c63d8234b45f60f9df4624f081fa2ef Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 21:14:45 +0800 Subject: [PATCH 138/179] chore: update default grid --- frontend/rust-lib/flowy-grid/src/util.rs | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index bbc2d1b642..11c5f5a106 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -3,37 +3,25 @@ use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; use flowy_sync::client_grid::GridBuilder; pub fn make_default_grid() -> BuildGridContext { + // text let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default()) .name("Name") .visibility(true) .build(); // single select - let single_select = SingleSelectTypeOptionBuilder::default() - .option(SelectOption::new("Done")) - .option(SelectOption::new("Unknown")) - .option(SelectOption::new("Progress")); - let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build(); - - //multiple select - let multi_select = MultiSelectTypeOptionBuilder::default() - .option(SelectOption::new("A")) - .option(SelectOption::new("B")) - .option(SelectOption::new("C")); - let multi_select_field = FieldBuilder::new(multi_select) - .name("Alphabet") - .visibility(true) - .build(); + let single_select = SingleSelectTypeOptionBuilder::default(); + let single_select_field = FieldBuilder::new(single_select).name("Type").visibility(true).build(); + // checkbox let checkbox_field = FieldBuilder::from_field_type(&FieldType::Checkbox) - .name("isReady") + .name("Done") .visibility(true) .build(); GridBuilder::default() .add_field(text_field) .add_field(single_select_field) - .add_field(multi_select_field) .add_field(checkbox_field) .add_empty_row() .add_empty_row() From a19536d525e4fcf42e236f53ca64667e9fa7c638 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 21:34:14 +0800 Subject: [PATCH 139/179] chore: disable time format temporarily --- .../src/services/field/type_options/date_type_option.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 2c9ab7c40e..e2b7a09290 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -41,7 +41,7 @@ impl DateTypeOption { } fn fmt_str(&self) -> String { - format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) + format!("{}", self.date_format.format_str()) } } From 722bacd118d328eaac4006528cb31473bd2753ed Mon Sep 17 00:00:00 2001 From: hewyyy Date: Mon, 11 Apr 2022 18:12:39 -0400 Subject: [PATCH 140/179] fix: update view after delete to fix consecutive delete bug --- .../lib/workspace/application/view/view_bloc.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart b/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart index 1528600236..5b5a953922 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart @@ -34,12 +34,14 @@ class ViewBloc extends Bloc { }, viewDidUpdate: (e) { e.result.fold( - (view) => emit(state.copyWith(view: view, successOrFailure: left(unit))), + (view) => + emit(state.copyWith(view: view, successOrFailure: left(unit))), (error) => emit(state.copyWith(successOrFailure: right(error))), ); }, rename: (e) async { - final result = await service.updateView(viewId: view.id, name: e.newName); + final result = + await service.updateView(viewId: view.id, name: e.newName); emit( result.fold( (l) => state.copyWith(successOrFailure: left(unit)), @@ -49,6 +51,7 @@ class ViewBloc extends Bloc { }, delete: (e) async { final result = await service.delete(viewId: view.id); + await service.updateView(viewId: view.id); emit( result.fold( (l) => state.copyWith(successOrFailure: left(unit)), @@ -83,7 +86,8 @@ class ViewEvent with _$ViewEvent { const factory ViewEvent.rename(String newName) = Rename; const factory ViewEvent.delete() = Delete; const factory ViewEvent.duplicate() = Duplicate; - const factory ViewEvent.viewDidUpdate(Either result) = ViewDidUpdate; + const factory ViewEvent.viewDidUpdate(Either result) = + ViewDidUpdate; } @freezed From ce21c3207cbb27e9f0d45e86c14e0bf1eb16a835 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 12 Apr 2022 07:48:59 +0800 Subject: [PATCH 141/179] chore: build flowy_sdk as static lib in macOS --- frontend/Makefile.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 9cfc352d56..fac2b4a7d7 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -25,8 +25,8 @@ CURRENT_APP_VERSION = "0.0.4" FEATURES = "flutter" PRODUCT_NAME = "AppFlowy" #CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html -CRATE_TYPE = "cdylib" -SDK_EXT = "dylib" +CRATE_TYPE = "staticlib" +SDK_EXT = "a" APP_ENVIRONMENT = "local" FLUTTER_FLOWY_SDK_PATH="app_flowy/packages/flowy_sdk" PROTOBUF_DERIVE_CACHE="../shared-lib/flowy-derive/src/derive_cache/derive_cache.rs" From cd14598199049649598048b91d5a66bdc64f6c37 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 11 Apr 2022 22:07:07 +0800 Subject: [PATCH 142/179] chore: update archive package path --- frontend/scripts/makefile/flutter.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/scripts/makefile/flutter.toml b/frontend/scripts/makefile/flutter.toml index 6824a60deb..fcf599af9e 100644 --- a/frontend/scripts/makefile/flutter.toml +++ b/frontend/scripts/makefile/flutter.toml @@ -117,7 +117,7 @@ linux_alias = "create-release-archive-linux" [tasks.create-release-archive-linux] script = [ - "cd ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${VERSION}/${TARGET_OS}/Release", + "cd ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/product/${APP_VERSION}/${TARGET_OS}/Release", "tar -czf ${PRODUCT_NAME}-${TARGET_OS}-x86.tar.gz *" ] From a0490341103962fabc170154be21bf0369ae7b51 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 12 Apr 2022 10:06:47 +0800 Subject: [PATCH 143/179] chore: support including time on date type --- frontend/Makefile.toml | 15 +- .../app_flowy/assets/translations/en.json | 1 + .../grid/cell_bloc/select_option_service.dart | 10 +- .../application/grid/field/field_service.dart | 4 +- .../grid/field/type_option/date_bloc.dart | 31 ++-- .../grid/src/widgets/cell/date_cell.dart | 19 ++- .../src/widgets/header/type_option/date.dart | 32 ++++ .../dart_event/flowy-grid/dart_event.dart | 20 +-- .../app_flowy/packages/flowy_sdk/lib/ffi.dart | 4 +- .../flowy-grid-data-model/grid.pb.dart | 36 ++-- .../flowy-grid-data-model/grid.pbjson.dart | 10 +- .../flowy-grid/date_type_option.pb.dart | 14 ++ .../flowy-grid/date_type_option.pbjson.dart | 3 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 12 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 8 +- .../flowy_sdk/macos/flowy_sdk.podspec | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 24 ++- frontend/rust-lib/flowy-grid/src/event_map.rs | 18 +- .../src/protobuf/model/date_type_option.rs | 48 +++++- .../src/protobuf/model/event_map.rs | 32 ++-- .../src/protobuf/proto/date_type_option.proto | 1 + .../src/protobuf/proto/event_map.proto | 6 +- .../field/type_options/date_type_option.rs | 159 +++++++++--------- .../flowy-grid/src/services/grid_editor.rs | 8 +- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 16 +- .../src/entities/grid.rs | 10 +- .../src/protobuf/model/grid.rs | 76 ++++----- .../src/protobuf/proto/grid.proto | 2 +- 29 files changed, 381 insertions(+), 244 deletions(-) diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index fac2b4a7d7..65f01b6a93 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -24,7 +24,20 @@ LIB_NAME = "dart_ffi" CURRENT_APP_VERSION = "0.0.4" FEATURES = "flutter" PRODUCT_NAME = "AppFlowy" -#CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html +# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html +# If you update the macOS's CRATE_TYPE, don't forget to update the +# flowy_sdk.podspec +# for staticlib: +# s.static_framework = true +# s.vendored_libraries = "libdart_ffi.a" +# for cdylib: +# s.vendored_libraries = "libdart_ffi.dylib" +# +# Remember to update the ffi.dart: +# for staticlib: +# if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a'); +# for cdylib: +# if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib'); CRATE_TYPE = "staticlib" SDK_EXT = "a" APP_ENVIRONMENT = "local" diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 83a7826918..97b0d162ef 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -162,6 +162,7 @@ "multiSelectFieldName": "Multiselect", "numberFormat": " Number format", "dateFormat": " Date format", + "includeTime": " Include time", "dateFormatFriendly": "Month Day,Year", "dateFormatISO": "Year-Month-Day", "dateFormatLocal": "Month/Month/Day", diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart index 34b977b5e3..65a05e4a5b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart @@ -24,7 +24,7 @@ class SelectOptionService { final payload = SelectOptionChangesetPayload.create() ..insertOption = option ..cellIdentifier = cellIdentifier; - return GridEventApplySelectOptionChangeset(payload).send(); + return GridEventUpdateSelectOption(payload).send(); }, (r) => right(r), ); @@ -45,7 +45,7 @@ class SelectOptionService { final payload = SelectOptionChangesetPayload.create() ..updateOption = option ..cellIdentifier = cellIdentifier; - return GridEventApplySelectOptionChangeset(payload).send(); + return GridEventUpdateSelectOption(payload).send(); } Future> delete({ @@ -63,7 +63,7 @@ class SelectOptionService { ..deleteOption = option ..cellIdentifier = cellIdentifier; - return GridEventApplySelectOptionChangeset(payload).send(); + return GridEventUpdateSelectOption(payload).send(); } Future> getOpitonContext({ @@ -90,7 +90,7 @@ class SelectOptionService { ..fieldId = fieldId ..rowId = rowId ..insertOptionId = optionId; - return GridEventApplySelectOptionCellChangeset(payload).send(); + return GridEventUpdateCellSelectOption(payload).send(); } Future> remove({ @@ -104,6 +104,6 @@ class SelectOptionService { ..fieldId = fieldId ..rowId = rowId ..deleteOptionId = optionId; - return GridEventApplySelectOptionCellChangeset(payload).send(); + return GridEventUpdateCellSelectOption(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index bdf8c0d261..c058bcd36c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -65,7 +65,7 @@ class FieldService { List? typeOptionData, String? startFieldId, }) { - var payload = CreateFieldPayload.create() + var payload = InsertFieldPayload.create() ..gridId = gridId ..field_2 = field ..typeOptionData = typeOptionData ?? []; @@ -74,7 +74,7 @@ class FieldService { payload.startFieldId = startFieldId; } - return GridEventCreateField(payload).send(); + return GridEventInsertField(payload).send(); } Future> deleteField({ diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart index 0cf842a171..c0a232a84f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -11,27 +11,37 @@ class DateTypeOptionBloc extends Bloc (event, emit) async { event.map( didSelectDateFormat: (_DidSelectDateFormat value) { - emit(state.copyWith(typeOption: _updateDateFormat(value.format))); + emit(state.copyWith(typeOption: _updateTypeOption(dateFormat: value.format))); }, didSelectTimeFormat: (_DidSelectTimeFormat value) { - emit(state.copyWith(typeOption: _updateTimeFormat(value.format))); + emit(state.copyWith(typeOption: _updateTypeOption(timeFormat: value.format))); + }, + includeTime: (_IncludeTime value) { + emit(state.copyWith(typeOption: _updateTypeOption(includeTime: value.includeTime))); }, ); }, ); } - DateTypeOption _updateTimeFormat(TimeFormat format) { + DateTypeOption _updateTypeOption({ + DateFormat? dateFormat, + TimeFormat? timeFormat, + bool? includeTime, + }) { state.typeOption.freeze(); return state.typeOption.rebuild((typeOption) { - typeOption.timeFormat = format; - }); - } + if (dateFormat != null) { + typeOption.dateFormat = dateFormat; + } - DateTypeOption _updateDateFormat(DateFormat format) { - state.typeOption.freeze(); - return state.typeOption.rebuild((typeOption) { - typeOption.dateFormat = format; + if (timeFormat != null) { + typeOption.timeFormat = timeFormat; + } + + if (includeTime != null) { + typeOption.includeTime = includeTime; + } }); } @@ -45,6 +55,7 @@ class DateTypeOptionBloc extends Bloc class DateTypeOptionEvent with _$DateTypeOptionEvent { const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) = _DidSelectDateFormat; const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) = _DidSelectTimeFormat; + const factory DateTypeOptionEvent.includeTime(bool includeTime) = _IncludeTime; } @freezed diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index 24351a425a..990aef30b7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -43,9 +43,9 @@ class _DateCellState extends State { _CellCalendar.show( context, onSelected: (day) { - widget.setFocus(context, false); context.read().add(DateCellEvent.selectDay(day)); }, + onDismissed: () => widget.setFocus(context, false), ); }, child: MouseRegion( @@ -71,17 +71,22 @@ final kToday = DateTime.now(); final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day); final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day); -class _CellCalendar extends StatefulWidget { +class _CellCalendar extends StatefulWidget with FlowyOverlayDelegate { final void Function(DateTime) onSelected; - const _CellCalendar({required this.onSelected, Key? key}) : super(key: key); + final VoidCallback onDismissed; + const _CellCalendar({required this.onSelected, required this.onDismissed, Key? key}) : super(key: key); @override State<_CellCalendar> createState() => _CellCalendarState(); - static Future show(BuildContext context, {required void Function(DateTime) onSelected}) async { + static Future show( + BuildContext context, { + required void Function(DateTime) onSelected, + required VoidCallback onDismissed, + }) async { _CellCalendar.remove(context); final window = await getWindowInfo(); - final calendar = _CellCalendar(onSelected: onSelected); + final calendar = _CellCalendar(onSelected: onSelected, onDismissed: onDismissed); const size = Size(460, 400); FlowyOverlay.of(context).insertWithRect( widget: OverlayContainer( @@ -93,6 +98,7 @@ class _CellCalendar extends StatefulWidget { anchorSize: window.frame.size, anchorDirection: AnchorDirection.center, style: FlowyOverlayStyle(blur: false), + delegate: calendar, ); } @@ -103,6 +109,9 @@ class _CellCalendar extends StatefulWidget { static String identifier() { return (_CellCalendar).toString(); } + + @override + void didRemove() => onDismissed(); } class _CellCalendarState extends State<_CellCalendar> { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index e4365a9a1a..a580bbebf1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -52,6 +52,7 @@ class DateTypeOptionWidget extends TypeOptionWidget { return Column(children: [ _dateFormatButton(context, state.typeOption.dateFormat), _timeFormatButton(context, state.typeOption.timeFormat), + const _IncludeTimeButton(), ]); }, ), @@ -102,6 +103,37 @@ class DateTypeOptionWidget extends TypeOptionWidget { } } +class _IncludeTimeButton extends StatelessWidget { + const _IncludeTimeButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocSelector( + selector: (state) => state.typeOption.includeTime, + builder: (context, includeTime) { + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: Padding( + padding: GridSize.typeOptionContentInsets, + child: Row( + children: [ + FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(), fontSize: 12), + const Spacer(), + Switch( + value: includeTime, + onChanged: (newValue) { + context.read().add(DateTypeOptionEvent.includeTime(newValue)); + }, + ), + ], + ), + ), + ); + }, + ); + } +} + class DateFormatList extends StatelessWidget { final DateFormat selectedFormat; final Function(DateFormat format) onSelected; 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 93a0abfee2..a8fd9add65 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -69,13 +69,13 @@ class GridEventUpdateField { } } -class GridEventCreateField { - CreateFieldPayload request; - GridEventCreateField(this.request); +class GridEventInsertField { + InsertFieldPayload request; + GridEventInsertField(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.CreateField.toString() + ..event = GridEvent.InsertField.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) @@ -188,13 +188,13 @@ class GridEventGetSelectOptionContext { } } -class GridEventApplySelectOptionChangeset { +class GridEventUpdateSelectOption { SelectOptionChangesetPayload request; - GridEventApplySelectOptionChangeset(this.request); + GridEventUpdateSelectOption(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.ApplySelectOptionChangeset.toString() + ..event = GridEvent.UpdateSelectOption.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) @@ -307,13 +307,13 @@ class GridEventUpdateCell { } } -class GridEventApplySelectOptionCellChangeset { +class GridEventUpdateCellSelectOption { SelectOptionCellChangesetPayload request; - GridEventApplySelectOptionCellChangeset(this.request); + GridEventUpdateCellSelectOption(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.ApplySelectOptionCellChangeset.toString() + ..event = GridEvent.UpdateCellSelectOption.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/ffi.dart b/frontend/app_flowy/packages/flowy_sdk/lib/ffi.dart index 798c33b318..0ade770a23 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/ffi.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/ffi.dart @@ -16,8 +16,8 @@ DynamicLibrary _open() { final prefix = "${Directory.current.path}/.sandbox"; if (Platform.isLinux) return DynamicLibrary.open('${prefix}/libdart_ffi.so'); if (Platform.isAndroid) return DynamicLibrary.open('${prefix}/libdart_ffi.so'); - if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib'); - if (Platform.isIOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib'); + if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a'); + if (Platform.isIOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a'); if (Platform.isWindows) return DynamicLibrary.open('${prefix}/dart_ffi.dll'); } else { if (Platform.isLinux) return DynamicLibrary.open('libdart_ffi.so'); 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 2c3a848729..fac1ee178a 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 @@ -1478,17 +1478,17 @@ class CreateRowPayload extends $pb.GeneratedMessage { void clearStartRowId() => clearField(2); } -enum CreateFieldPayload_OneOfStartFieldId { +enum InsertFieldPayload_OneOfStartFieldId { startFieldId, notSet } -class CreateFieldPayload extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CreateFieldPayload_OneOfStartFieldId> _CreateFieldPayload_OneOfStartFieldIdByTag = { - 4 : CreateFieldPayload_OneOfStartFieldId.startFieldId, - 0 : CreateFieldPayload_OneOfStartFieldId.notSet +class InsertFieldPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, InsertFieldPayload_OneOfStartFieldId> _InsertFieldPayload_OneOfStartFieldIdByTag = { + 4 : InsertFieldPayload_OneOfStartFieldId.startFieldId, + 0 : InsertFieldPayload_OneOfStartFieldId.notSet }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateFieldPayload', createEmptyInstance: create) + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InsertFieldPayload', createEmptyInstance: create) ..oo(0, [4]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create) @@ -1497,8 +1497,8 @@ class CreateFieldPayload extends $pb.GeneratedMessage { ..hasRequiredFields = false ; - CreateFieldPayload._() : super(); - factory CreateFieldPayload({ + InsertFieldPayload._() : super(); + factory InsertFieldPayload({ $core.String? gridId, Field? field_2, $core.List<$core.int>? typeOptionData, @@ -1519,28 +1519,28 @@ class CreateFieldPayload extends $pb.GeneratedMessage { } return _result; } - factory CreateFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CreateFieldPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory InsertFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory InsertFieldPayload.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') - CreateFieldPayload clone() => CreateFieldPayload()..mergeFromMessage(this); + InsertFieldPayload clone() => InsertFieldPayload()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - CreateFieldPayload copyWith(void Function(CreateFieldPayload) updates) => super.copyWith((message) => updates(message as CreateFieldPayload)) as CreateFieldPayload; // ignore: deprecated_member_use + InsertFieldPayload copyWith(void Function(InsertFieldPayload) updates) => super.copyWith((message) => updates(message as InsertFieldPayload)) as InsertFieldPayload; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static CreateFieldPayload create() => CreateFieldPayload._(); - CreateFieldPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static InsertFieldPayload create() => InsertFieldPayload._(); + InsertFieldPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static CreateFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CreateFieldPayload? _defaultInstance; + static InsertFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static InsertFieldPayload? _defaultInstance; - CreateFieldPayload_OneOfStartFieldId whichOneOfStartFieldId() => _CreateFieldPayload_OneOfStartFieldIdByTag[$_whichOneof(0)]!; + InsertFieldPayload_OneOfStartFieldId whichOneOfStartFieldId() => _InsertFieldPayload_OneOfStartFieldIdByTag[$_whichOneof(0)]!; void clearOneOfStartFieldId() => clearField($_whichOneof(0)); @$pb.TagNumber(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 de56fa5748..0f8165fb8d 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 @@ -305,9 +305,9 @@ const CreateRowPayload$json = const { /// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk'); -@$core.Deprecated('Use createFieldPayloadDescriptor instead') -const CreateFieldPayload$json = const { - '1': 'CreateFieldPayload', +@$core.Deprecated('Use insertFieldPayloadDescriptor instead') +const InsertFieldPayload$json = const { + '1': 'InsertFieldPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'field'}, @@ -319,8 +319,8 @@ const CreateFieldPayload$json = const { ], }; -/// Descriptor for `CreateFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createFieldPayloadDescriptor = $convert.base64Decode('ChJDcmVhdGVGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ='); +/// Descriptor for `InsertFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List insertFieldPayloadDescriptor = $convert.base64Decode('ChJJbnNlcnRGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ='); @$core.Deprecated('Use queryFieldPayloadDescriptor instead') const QueryFieldPayload$json = const { '1': 'QueryFieldPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart index 85c5e55111..db19e676d1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart @@ -17,6 +17,7 @@ class DateTypeOption extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateTypeOption', 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) + ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'includeTime') ..hasRequiredFields = false ; @@ -24,6 +25,7 @@ class DateTypeOption extends $pb.GeneratedMessage { factory DateTypeOption({ DateFormat? dateFormat, TimeFormat? timeFormat, + $core.bool? includeTime, }) { final _result = create(); if (dateFormat != null) { @@ -32,6 +34,9 @@ class DateTypeOption extends $pb.GeneratedMessage { if (timeFormat != null) { _result.timeFormat = timeFormat; } + if (includeTime != null) { + _result.includeTime = includeTime; + } return _result; } factory DateTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -72,5 +77,14 @@ class DateTypeOption extends $pb.GeneratedMessage { $core.bool hasTimeFormat() => $_has(1); @$pb.TagNumber(2) void clearTimeFormat() => clearField(2); + + @$pb.TagNumber(3) + $core.bool get includeTime => $_getBF(2); + @$pb.TagNumber(3) + set includeTime($core.bool v) { $_setBool(2, v); } + @$pb.TagNumber(3) + $core.bool hasIncludeTime() => $_has(2); + @$pb.TagNumber(3) + void clearIncludeTime() => clearField(3); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart index 9acf67241b..f419cc0e95 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart @@ -38,8 +38,9 @@ const DateTypeOption$json = const { '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'}, + const {'1': 'include_time', '3': 3, '4': 1, '5': 8, '10': 'includeTime'}, ], }; /// Descriptor for `DateTypeOption`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List dateTypeOptionDescriptor = $convert.base64Decode('Cg5EYXRlVHlwZU9wdGlvbhIsCgtkYXRlX2Zvcm1hdBgBIAEoDjILLkRhdGVGb3JtYXRSCmRhdGVGb3JtYXQSLAoLdGltZV9mb3JtYXQYAiABKA4yCy5UaW1lRm9ybWF0Ugp0aW1lRm9ybWF0'); +final $typed_data.Uint8List dateTypeOptionDescriptor = $convert.base64Decode('Cg5EYXRlVHlwZU9wdGlvbhIsCgtkYXRlX2Zvcm1hdBgBIAEoDjILLkRhdGVGb3JtYXRSCmRhdGVGb3JtYXQSLAoLdGltZV9mb3JtYXQYAiABKA4yCy5UaW1lRm9ybWF0Ugp0aW1lRm9ybWF0EiEKDGluY2x1ZGVfdGltZRgDIAEoCFILaW5jbHVkZVRpbWU='); 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 5be5844119..b4bde9790b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -14,42 +14,42 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks'); static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField'); - static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField'); + static const GridEvent InsertField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InsertField'); static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField'); static const GridEvent SwitchToField = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SwitchToField'); static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext'); static const GridEvent NewSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewSelectOption'); static const GridEvent GetSelectOptionContext = GridEvent._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetSelectOptionContext'); - static const GridEvent ApplySelectOptionChangeset = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); + static const GridEvent UpdateSelectOption = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateSelectOption'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent DeleteRow = GridEvent._(52, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteRow'); static const GridEvent DuplicateRow = GridEvent._(53, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateRow'); static const GridEvent GetCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCell'); static const GridEvent UpdateCell = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); - static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); + static const GridEvent UpdateCellSelectOption = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCellSelectOption'); static const $core.List values = [ GetGridData, GetGridBlocks, GetFields, UpdateField, - CreateField, + InsertField, DeleteField, SwitchToField, DuplicateField, GetEditFieldContext, NewSelectOption, GetSelectOptionContext, - ApplySelectOptionChangeset, + UpdateSelectOption, CreateRow, GetRow, DeleteRow, DuplicateRow, GetCell, UpdateCell, - ApplySelectOptionCellChangeset, + UpdateCellSelectOption, ]; 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 2f2921564b..272b82e375 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -16,23 +16,23 @@ const GridEvent$json = const { const {'1': 'GetGridBlocks', '2': 1}, const {'1': 'GetFields', '2': 10}, const {'1': 'UpdateField', '2': 11}, - const {'1': 'CreateField', '2': 12}, + const {'1': 'InsertField', '2': 12}, const {'1': 'DeleteField', '2': 13}, const {'1': 'SwitchToField', '2': 14}, const {'1': 'DuplicateField', '2': 15}, const {'1': 'GetEditFieldContext', '2': 16}, const {'1': 'NewSelectOption', '2': 30}, const {'1': 'GetSelectOptionContext', '2': 31}, - const {'1': 'ApplySelectOptionChangeset', '2': 32}, + const {'1': 'UpdateSelectOption', '2': 32}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, const {'1': 'DeleteRow', '2': 52}, const {'1': 'DuplicateRow', '2': 53}, const {'1': 'GetCell', '2': 70}, const {'1': 'UpdateCell', '2': 71}, - const {'1': 'ApplySelectOptionCellChangeset', '2': 72}, + const {'1': 'UpdateCellSelectOption', '2': 72}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg0KCURlbGV0ZVJvdxA0EhAKDER1cGxpY2F0ZVJvdxA1EgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSIgoeQXBwbHlTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0EEg='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtJbnNlcnRGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIWChJVcGRhdGVTZWxlY3RPcHRpb24QIBINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxINCglEZWxldGVSb3cQNBIQCgxEdXBsaWNhdGVSb3cQNRILCgdHZXRDZWxsEEYSDgoKVXBkYXRlQ2VsbBBHEhoKFlVwZGF0ZUNlbGxTZWxlY3RPcHRpb24QSA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec b/frontend/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec index 4dd9a055f9..497388b99f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec +++ b/frontend/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec @@ -20,6 +20,6 @@ A new flutter plugin project. s.platform = :osx, '10.11' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.swift_version = '5.0' - # s.static_framework = true - s.vendored_libraries = "libdart_ffi.dylib" + s.static_framework = true + s.vendored_libraries = "libdart_ffi.a" end diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index abe9dd59a7..e9f0bda61e 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -62,13 +62,13 @@ pub(crate) async fn update_field_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn create_field_handler( - data: Data, +pub(crate) async fn insert_field_handler( + data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let params: CreateFieldParams = data.into_inner().try_into()?; + let params: InsertFieldParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let _ = editor.create_field(params).await?; + let _ = editor.insert_field(params).await?; Ok(()) } @@ -243,7 +243,7 @@ pub(crate) async fn new_select_option_handler(data: Data) -> D } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn select_option_changeset_handler( +pub(crate) async fn update_select_option_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { @@ -281,6 +281,18 @@ pub(crate) async fn select_option_changeset_handler( } Ok(()) } +// +// #[tracing::instrument(level = "debug", skip_all, err)] +// pub(crate) async fn update_date_option_handler( +// data: Data, +// manager: AppData>, +// ) -> Result<(), FlowyError> { +// let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?; +// let editor = manager.get_grid_editor(¶ms.grid_id)?; +// let changeset: CellChangeset = params.into(); +// let _ = editor.update_cell(changeset).await?; +// Ok(()) +// } #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_select_option_handler( @@ -304,7 +316,7 @@ pub(crate) async fn get_select_option_handler( } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn select_option_cell_changeset_handler( +pub(crate) async fn update_cell_select_option_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index e2e138aee2..08a2a25313 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -13,7 +13,7 @@ pub fn create(grid_manager: Arc) -> Module { // Field .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) - .event(GridEvent::CreateField, create_field_handler) + .event(GridEvent::InsertField, insert_field_handler) .event(GridEvent::DeleteField, delete_field_handler) .event(GridEvent::SwitchToField, switch_to_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) @@ -27,12 +27,10 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::UpdateCell, update_cell_handler) // SelectOption .event(GridEvent::NewSelectOption, new_select_option_handler) - .event(GridEvent::ApplySelectOptionChangeset, select_option_changeset_handler) + .event(GridEvent::UpdateSelectOption, update_select_option_handler) .event(GridEvent::GetSelectOptionContext, get_select_option_handler) - .event( - GridEvent::ApplySelectOptionCellChangeset, - select_option_cell_changeset_handler, - ) + .event(GridEvent::UpdateCellSelectOption, update_cell_select_option_handler) + // .event(GridEvent::GetEditFieldContext, get_field_context_handler); module @@ -53,8 +51,8 @@ pub enum GridEvent { #[event(input = "FieldChangesetPayload")] UpdateField = 11, - #[event(input = "CreateFieldPayload")] - CreateField = 12, + #[event(input = "InsertFieldPayload")] + InsertField = 12, #[event(input = "FieldIdentifierPayload")] DeleteField = 13, @@ -75,7 +73,7 @@ pub enum GridEvent { GetSelectOptionContext = 31, #[event(input = "SelectOptionChangesetPayload")] - ApplySelectOptionChangeset = 32, + UpdateSelectOption = 32, #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 50, @@ -96,5 +94,5 @@ pub enum GridEvent { UpdateCell = 71, #[event(input = "SelectOptionCellChangesetPayload")] - ApplySelectOptionCellChangeset = 72, + UpdateCellSelectOption = 72, } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs index 5287fa32d6..223d6f322c 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs @@ -28,6 +28,7 @@ pub struct DateTypeOption { // message fields pub date_format: DateFormat, pub time_format: TimeFormat, + pub include_time: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -73,6 +74,21 @@ impl DateTypeOption { pub fn set_time_format(&mut self, v: TimeFormat) { self.time_format = v; } + + // bool include_time = 3; + + + pub fn get_include_time(&self) -> bool { + self.include_time + } + pub fn clear_include_time(&mut self) { + self.include_time = false; + } + + // Param is passed by value, moved + pub fn set_include_time(&mut self, v: bool) { + self.include_time = v; + } } impl ::protobuf::Message for DateTypeOption { @@ -90,6 +106,13 @@ impl ::protobuf::Message for DateTypeOption { 2 => { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.time_format, 2, &mut self.unknown_fields)? }, + 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.include_time = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -108,6 +131,9 @@ impl ::protobuf::Message for DateTypeOption { if self.time_format != TimeFormat::TwelveHour { my_size += ::protobuf::rt::enum_size(2, self.time_format); } + if self.include_time != false { + my_size += 2; + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -120,6 +146,9 @@ impl ::protobuf::Message for DateTypeOption { if self.time_format != TimeFormat::TwelveHour { os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.time_format))?; } + if self.include_time != false { + os.write_bool(3, self.include_time)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -168,6 +197,11 @@ impl ::protobuf::Message for DateTypeOption { |m: &DateTypeOption| { &m.time_format }, |m: &mut DateTypeOption| { &mut m.time_format }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "include_time", + |m: &DateTypeOption| { &m.include_time }, + |m: &mut DateTypeOption| { &mut m.include_time }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "DateTypeOption", fields, @@ -186,6 +220,7 @@ impl ::protobuf::Clear for DateTypeOption { fn clear(&mut self) { self.date_format = DateFormat::Local; self.time_format = TimeFormat::TwelveHour; + self.include_time = false; self.unknown_fields.clear(); } } @@ -309,12 +344,13 @@ impl ::protobuf::reflect::ProtobufValue for TimeFormat { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x16date_type_option.proto\"l\n\x0eDateTypeOption\x12,\n\x0bdate_forma\ - t\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btime_forma\ - t\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat*6\n\nDateFormat\x12\ - \t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\ - \x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\ - \x12\x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\ + \n\x16date_type_option.proto\"\x8f\x01\n\x0eDateTypeOption\x12,\n\x0bdat\ + e_format\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btim\ + e_format\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat\x12!\n\x0cinc\ + lude_time\x18\x03\x20\x01(\x08R\x0bincludeTime*6\n\nDateFormat\x12\t\n\ + \x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\x0c\ + \n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\x12\ + \x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; 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 10bee819ce..c474939b47 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -29,21 +29,21 @@ pub enum GridEvent { GetGridBlocks = 1, GetFields = 10, UpdateField = 11, - CreateField = 12, + InsertField = 12, DeleteField = 13, SwitchToField = 14, DuplicateField = 15, GetEditFieldContext = 16, NewSelectOption = 30, GetSelectOptionContext = 31, - ApplySelectOptionChangeset = 32, + UpdateSelectOption = 32, CreateRow = 50, GetRow = 51, DeleteRow = 52, DuplicateRow = 53, GetCell = 70, UpdateCell = 71, - ApplySelectOptionCellChangeset = 72, + UpdateCellSelectOption = 72, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -57,21 +57,21 @@ impl ::protobuf::ProtobufEnum for GridEvent { 1 => ::std::option::Option::Some(GridEvent::GetGridBlocks), 10 => ::std::option::Option::Some(GridEvent::GetFields), 11 => ::std::option::Option::Some(GridEvent::UpdateField), - 12 => ::std::option::Option::Some(GridEvent::CreateField), + 12 => ::std::option::Option::Some(GridEvent::InsertField), 13 => ::std::option::Option::Some(GridEvent::DeleteField), 14 => ::std::option::Option::Some(GridEvent::SwitchToField), 15 => ::std::option::Option::Some(GridEvent::DuplicateField), 16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext), 30 => ::std::option::Option::Some(GridEvent::NewSelectOption), 31 => ::std::option::Option::Some(GridEvent::GetSelectOptionContext), - 32 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), + 32 => ::std::option::Option::Some(GridEvent::UpdateSelectOption), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), 52 => ::std::option::Option::Some(GridEvent::DeleteRow), 53 => ::std::option::Option::Some(GridEvent::DuplicateRow), 70 => ::std::option::Option::Some(GridEvent::GetCell), 71 => ::std::option::Option::Some(GridEvent::UpdateCell), - 72 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), + 72 => ::std::option::Option::Some(GridEvent::UpdateCellSelectOption), _ => ::std::option::Option::None } } @@ -82,21 +82,21 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetGridBlocks, GridEvent::GetFields, GridEvent::UpdateField, - GridEvent::CreateField, + GridEvent::InsertField, GridEvent::DeleteField, GridEvent::SwitchToField, GridEvent::DuplicateField, GridEvent::GetEditFieldContext, GridEvent::NewSelectOption, GridEvent::GetSelectOptionContext, - GridEvent::ApplySelectOptionChangeset, + GridEvent::UpdateSelectOption, GridEvent::CreateRow, GridEvent::GetRow, GridEvent::DeleteRow, GridEvent::DuplicateRow, GridEvent::GetCell, GridEvent::UpdateCell, - GridEvent::ApplySelectOptionCellChangeset, + GridEvent::UpdateCellSelectOption, ]; values } @@ -125,16 +125,16 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xff\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xef\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ - \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ + \x0bUpdateField\x10\x0b\x12\x0f\n\x0bInsertField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\ - lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x1e\n\ - \x1aApplySelectOptionChangeset\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\ - \x06GetRow\x103\x12\r\n\tDeleteRow\x104\x12\x10\n\x0cDuplicateRow\x105\ - \x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\"\n\x1eApplySe\ - lectOptionCellChangeset\x10Hb\x06proto3\ + lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x16\n\ + \x12UpdateSelectOption\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\x06GetRow\ + \x103\x12\r\n\tDeleteRow\x104\x12\x10\n\x0cDuplicateRow\x105\x12\x0b\n\ + \x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\x1a\n\x16UpdateCellSelec\ + tOption\x10Hb\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/date_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto index be42570348..6dbc5ae09b 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto @@ -3,6 +3,7 @@ syntax = "proto3"; message DateTypeOption { DateFormat date_format = 1; TimeFormat time_format = 2; + bool include_time = 3; } enum DateFormat { Local = 0; 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 9fad8dd7b1..eb66389430 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -5,19 +5,19 @@ enum GridEvent { GetGridBlocks = 1; GetFields = 10; UpdateField = 11; - CreateField = 12; + InsertField = 12; DeleteField = 13; SwitchToField = 14; DuplicateField = 15; GetEditFieldContext = 16; NewSelectOption = 30; GetSelectOptionContext = 31; - ApplySelectOptionChangeset = 32; + UpdateSelectOption = 32; CreateRow = 50; GetRow = 51; DeleteRow = 52; DuplicateRow = 53; GetCell = 70; UpdateCell = 71; - ApplySelectOptionCellChangeset = 72; + UpdateCellSelectOption = 72; } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index e2b7a09290..0ad2d9585a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -23,6 +23,9 @@ pub struct DateTypeOption { #[pb(index = 2)] pub time_format: TimeFormat, + + #[pb(index = 3)] + pub include_time: bool, } impl_type_option!(DateTypeOption, FieldType::DateTime); @@ -41,7 +44,11 @@ impl DateTypeOption { } fn fmt_str(&self) -> String { - format!("{}", self.date_format.format_str()) + if self.include_time { + format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) + } else { + format!("{}", self.date_format.format_str()) + } } } @@ -205,79 +212,79 @@ mod tests { ); } - // #[test] - // fn date_description_date_format_test() { - // let mut type_option = DateTypeOption::default(); - // let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - // for date_format in DateFormat::iter() { - // type_option.date_format = date_format; - // match date_format { - // DateFormat::Friendly => { - // assert_eq!( - // "Mar 14,2022 17:56".to_owned(), - // type_option.decode_cell_data(data("1647251762"), &field_meta) - // ); - // assert_eq!( - // "Mar 14,2022 17:56".to_owned(), - // type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) - // ); - // } - // DateFormat::US => { - // assert_eq!( - // "2022/03/14 17:56".to_owned(), - // type_option.decode_cell_data(data("1647251762"), &field_meta) - // ); - // assert_eq!( - // "2022/03/14 17:56".to_owned(), - // type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) - // ); - // } - // DateFormat::ISO => { - // assert_eq!( - // "2022-03-14 17:56".to_owned(), - // type_option.decode_cell_data(data("1647251762"), &field_meta) - // ); - // } - // DateFormat::Local => { - // assert_eq!( - // "2022/03/14 17:56".to_owned(), - // type_option.decode_cell_data(data("1647251762"), &field_meta) - // ); - // } - // } - // } - // } + #[test] + fn date_description_date_format_test() { + let mut type_option = DateTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + for date_format in DateFormat::iter() { + type_option.date_format = date_format; + match date_format { + DateFormat::Friendly => { + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + type_option.decode_cell_data(data("1647251762"), &field_meta) + ); + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) + ); + } + DateFormat::US => { + assert_eq!( + "2022/03/14 17:56".to_owned(), + type_option.decode_cell_data(data("1647251762"), &field_meta) + ); + assert_eq!( + "2022/03/14 17:56".to_owned(), + type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) + ); + } + DateFormat::ISO => { + assert_eq!( + "2022-03-14 17:56".to_owned(), + type_option.decode_cell_data(data("1647251762"), &field_meta) + ); + } + DateFormat::Local => { + assert_eq!( + "2022/03/14 17:56".to_owned(), + type_option.decode_cell_data(data("1647251762"), &field_meta) + ); + } + } + } + } - // #[test] - // fn date_description_time_format_test() { - // let mut type_option = DateTypeOption::default(); - // let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - // for time_format in TimeFormat::iter() { - // type_option.time_format = time_format; - // match time_format { - // TimeFormat::TwentyFourHour => { - // assert_eq!( - // "Mar 14,2022 17:56".to_owned(), - // type_option.today_from_timestamp(1647251762) - // ); - // assert_eq!( - // "Mar 14,2022 17:56".to_owned(), - // type_option.decode_cell_data(data("1647251762"), &field_meta) - // ); - // } - // TimeFormat::TwelveHour => { - // assert_eq!( - // "Mar 14,2022 05:56:02 PM".to_owned(), - // type_option.today_from_timestamp(1647251762) - // ); - // assert_eq!( - // "Mar 14,2022 05:56:02 PM".to_owned(), - // type_option.decode_cell_data(data("1647251762"), &field_meta) - // ); - // } - // } - // } - // } + #[test] + fn date_description_time_format_test() { + let mut type_option = DateTypeOption::default(); + let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); + for time_format in TimeFormat::iter() { + type_option.time_format = time_format; + match time_format { + TimeFormat::TwentyFourHour => { + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + type_option.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + type_option.decode_cell_data(data("1647251762"), &field_meta) + ); + } + TimeFormat::TwelveHour => { + assert_eq!( + "Mar 14,2022 05:56:02 PM".to_owned(), + type_option.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 05:56:02 PM".to_owned(), + type_option.decode_cell_data(data("1647251762"), &field_meta) + ); + } + } + } + } #[test] #[should_panic] @@ -286,7 +293,7 @@ mod tests { type_option.apply_changeset("he", None).unwrap(); } - // fn data(s: &str) -> String { - // TypeOptionCellData::new(s, FieldType::DateTime).json() - // } + fn data(s: &str) -> String { + TypeOptionCellData::new(s, FieldType::DateTime).json() + } } 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 50282e6b8a..f78adda837 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -51,8 +51,8 @@ impl ClientGridEditor { })) } - pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> { - let CreateFieldParams { + pub async fn insert_field(&self, params: InsertFieldParams) -> FlowyResult<()> { + let InsertFieldParams { field, type_option_data, start_field_id, @@ -483,6 +483,8 @@ impl JsonDeserializer for TypeOptionJsonDeserializer { fn deserialize(&self, type_option_data: Vec) -> CollaborateResult { // The type_option_data sent from Dart is serialized by protobuf. let builder = type_option_builder_from_bytes(type_option_data, &self.0); - Ok(builder.entry().json_str()) + let json = builder.entry().json_str(); + tracing::trace!("Deserialize type option data to: {}", json); + Ok(json) } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index aee5a4faa0..3c66f2355e 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -288,7 +288,7 @@ async fn grid_row_add_date_cell_test() { let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); assert_eq!( decode_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type).unwrap(), - "2022/03/16 08:31", + "2022/03/16", ); let scripts = vec![CreateRow { context }]; test.run_scripts(scripts).await; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 9d2dae5666..40ab75f780 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,8 +3,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ - BuildGridContext, CellChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, - GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, + BuildGridContext, CellChangeset, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, + GridBlockMetaChangeset, InsertFieldParams, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry, }; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_sync::client_grid::GridBuilder; @@ -18,7 +18,7 @@ use tokio::time::sleep; pub enum EditorScript { CreateField { - params: CreateFieldParams, + params: InsertFieldParams, }, UpdateField { changeset: FieldChangesetParams, @@ -124,7 +124,7 @@ impl GridEditorTest { self.field_count += 1; } - self.editor.create_field(params).await.unwrap(); + self.editor.insert_field(params).await.unwrap(); self.field_metas = self.editor.get_field_metas::(None).await.unwrap(); assert_eq!(self.field_count, self.field_metas.len()); } @@ -249,7 +249,7 @@ async fn get_row_metas(editor: &Arc) -> Vec> { .row_metas } -pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { +pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) { let field_meta = FieldBuilder::new(RichTextTypeOptionBuilder::default()) .name("Name") .visibility(true) @@ -273,7 +273,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { width: field_meta.width, }; - let params = CreateFieldParams { + let params = InsertFieldParams { grid_id: grid_id.to_owned(), field, type_option_data, @@ -282,7 +282,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { (params, cloned_field_meta) } -pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) { +pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) { let single_select = SingleSelectTypeOptionBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); @@ -305,7 +305,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet width: field_meta.width, }; - let params = CreateFieldParams { + let params = InsertFieldParams { grid_id: grid_id.to_owned(), field, type_option_data, 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 0c44edb4f9..eddbc4b19f 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -483,7 +483,7 @@ impl TryInto for CreateRowPayload { } #[derive(ProtoBuf, Default)] -pub struct CreateFieldPayload { +pub struct InsertFieldPayload { #[pb(index = 1)] pub grid_id: String, @@ -498,17 +498,17 @@ pub struct CreateFieldPayload { } #[derive(Clone)] -pub struct CreateFieldParams { +pub struct InsertFieldParams { pub grid_id: String, pub field: Field, pub type_option_data: Vec, pub start_field_id: Option, } -impl TryInto for CreateFieldPayload { +impl TryInto for InsertFieldPayload { type Error = ErrorCode; - fn try_into(self) -> Result { + fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; let _ = NotEmptyStr::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; @@ -517,7 +517,7 @@ impl TryInto for CreateFieldPayload { Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), }; - Ok(CreateFieldParams { + Ok(InsertFieldParams { grid_id: grid_id.0, field: self.field, type_option_data: self.type_option_data, diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 5d40483fdd..6f2e7d1787 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 @@ -5076,31 +5076,31 @@ impl ::protobuf::reflect::ProtobufValue for CreateRowPayload { } #[derive(PartialEq,Clone,Default)] -pub struct CreateFieldPayload { +pub struct InsertFieldPayload { // message fields pub grid_id: ::std::string::String, pub field: ::protobuf::SingularPtrField, pub type_option_data: ::std::vec::Vec, // message oneof groups - pub one_of_start_field_id: ::std::option::Option, + pub one_of_start_field_id: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a CreateFieldPayload { - fn default() -> &'a CreateFieldPayload { - ::default_instance() +impl<'a> ::std::default::Default for &'a InsertFieldPayload { + fn default() -> &'a InsertFieldPayload { + ::default_instance() } } #[derive(Clone,PartialEq,Debug)] -pub enum CreateFieldPayload_oneof_one_of_start_field_id { +pub enum InsertFieldPayload_oneof_one_of_start_field_id { start_field_id(::std::string::String), } -impl CreateFieldPayload { - pub fn new() -> CreateFieldPayload { +impl InsertFieldPayload { + pub fn new() -> InsertFieldPayload { ::std::default::Default::default() } @@ -5194,7 +5194,7 @@ impl CreateFieldPayload { pub fn get_start_field_id(&self) -> &str { match self.one_of_start_field_id { - ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v)) => v, + ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v)) => v, _ => "", } } @@ -5204,24 +5204,24 @@ impl CreateFieldPayload { pub fn has_start_field_id(&self) -> bool { match self.one_of_start_field_id { - ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(..)) => true, + ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(..)) => true, _ => false, } } // Param is passed by value, moved pub fn set_start_field_id(&mut self, v: ::std::string::String) { - self.one_of_start_field_id = ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) + self.one_of_start_field_id = ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) } // Mutable pointer to the field. pub fn mut_start_field_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(_)) = self.one_of_start_field_id { + if let ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(_)) = self.one_of_start_field_id { } else { - self.one_of_start_field_id = ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(::std::string::String::new())); + self.one_of_start_field_id = ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(::std::string::String::new())); } match self.one_of_start_field_id { - ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref mut v)) => v, + ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref mut v)) => v, _ => panic!(), } } @@ -5230,7 +5230,7 @@ impl CreateFieldPayload { pub fn take_start_field_id(&mut self) -> ::std::string::String { if self.has_start_field_id() { match self.one_of_start_field_id.take() { - ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) => v, + ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) => v, _ => panic!(), } } else { @@ -5239,7 +5239,7 @@ impl CreateFieldPayload { } } -impl ::protobuf::Message for CreateFieldPayload { +impl ::protobuf::Message for InsertFieldPayload { fn is_initialized(&self) -> bool { for v in &self.field { if !v.is_initialized() { @@ -5266,7 +5266,7 @@ impl ::protobuf::Message for CreateFieldPayload { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_start_field_id = ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(is.read_string()?)); + self.one_of_start_field_id = ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(is.read_string()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -5292,7 +5292,7 @@ impl ::protobuf::Message for CreateFieldPayload { } if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id { match v { - &CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => { + &InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => { my_size += ::protobuf::rt::string_size(4, &v); }, }; @@ -5316,7 +5316,7 @@ impl ::protobuf::Message for CreateFieldPayload { } if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id { match v { - &CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => { + &InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => { os.write_string(4, v)?; }, }; @@ -5351,8 +5351,8 @@ impl ::protobuf::Message for CreateFieldPayload { Self::descriptor_static() } - fn new() -> CreateFieldPayload { - CreateFieldPayload::new() + fn new() -> InsertFieldPayload { + InsertFieldPayload::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -5361,39 +5361,39 @@ impl ::protobuf::Message for CreateFieldPayload { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &CreateFieldPayload| { &m.grid_id }, - |m: &mut CreateFieldPayload| { &mut m.grid_id }, + |m: &InsertFieldPayload| { &m.grid_id }, + |m: &mut InsertFieldPayload| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "field", - |m: &CreateFieldPayload| { &m.field }, - |m: &mut CreateFieldPayload| { &mut m.field }, + |m: &InsertFieldPayload| { &m.field }, + |m: &mut InsertFieldPayload| { &mut m.field }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( "type_option_data", - |m: &CreateFieldPayload| { &m.type_option_data }, - |m: &mut CreateFieldPayload| { &mut m.type_option_data }, + |m: &InsertFieldPayload| { &m.type_option_data }, + |m: &mut InsertFieldPayload| { &mut m.type_option_data }, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "start_field_id", - CreateFieldPayload::has_start_field_id, - CreateFieldPayload::get_start_field_id, + InsertFieldPayload::has_start_field_id, + InsertFieldPayload::get_start_field_id, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CreateFieldPayload", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "InsertFieldPayload", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static CreateFieldPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CreateFieldPayload::new) + fn default_instance() -> &'static InsertFieldPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(InsertFieldPayload::new) } } -impl ::protobuf::Clear for CreateFieldPayload { +impl ::protobuf::Clear for InsertFieldPayload { fn clear(&mut self) { self.grid_id.clear(); self.field.clear(); @@ -5403,13 +5403,13 @@ impl ::protobuf::Clear for CreateFieldPayload { } } -impl ::std::fmt::Debug for CreateFieldPayload { +impl ::std::fmt::Debug for InsertFieldPayload { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CreateFieldPayload { +impl ::protobuf::reflect::ProtobufValue for InsertFieldPayload { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -6952,7 +6952,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\ \x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\ \x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0\ - R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPa\ + R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12InsertFieldPa\ yload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05fi\ eld\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ 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 a616ea8fd9..e5950858f0 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 @@ -98,7 +98,7 @@ message CreateRowPayload { string grid_id = 1; oneof one_of_start_row_id { string start_row_id = 2; }; } -message CreateFieldPayload { +message InsertFieldPayload { string grid_id = 1; Field field = 2; bytes type_option_data = 3; From f4b206d196155f2be66c659a603dfc97b3565934 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 12 Apr 2022 11:13:35 +0800 Subject: [PATCH 144/179] chore: config test log --- .github/workflows/rust_test.yml | 4 +- frontend/.vscode/launch.json | 4 +- frontend/Makefile.toml | 2 +- .../grid/src/widgets/cell/date_cell.dart | 48 +++++++-- frontend/rust-lib/flowy-folder/Cargo.toml | 2 +- .../src/services/app/controller.rs | 2 +- .../src/services/app/event_handler.rs | 4 +- .../src/services/trash/controller.rs | 2 +- .../src/services/trash/event_handler.rs | 10 +- .../src/services/view/controller.rs | 15 ++- .../src/services/view/event_handler.rs | 4 +- .../src/services/workspace/event_handler.rs | 10 +- .../field/type_options/date_type_option.rs | 33 +++--- .../field/type_options/text_type_option.rs | 100 +++++++++--------- .../rust-lib/flowy-net/src/handlers/mod.rs | 2 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 8 +- frontend/rust-lib/flowy-test/src/lib.rs | 2 +- .../flowy-text-block/src/event_handler.rs | 2 +- .../flowy-text-block/tests/editor/mod.rs | 2 +- .../flowy-user/src/handlers/auth_handler.rs | 3 +- .../flowy-user/src/handlers/user_handler.rs | 12 +-- .../flowy-user/src/services/database.rs | 2 +- frontend/rust-lib/lib-log/src/lib.rs | 2 +- 23 files changed, 158 insertions(+), 117 deletions(-) diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml index 84617fb2c2..998f6378e1 100644 --- a/.github/workflows/rust_test.yml +++ b/.github/workflows/rust_test.yml @@ -44,8 +44,8 @@ jobs: - name: Run rust-lib tests working-directory: frontend/rust-lib - run: cargo test --no-default-features + run: RUST_LOG=info cargo test --no-default-features - name: Run shared-lib tests working-directory: shared-lib - run: cargo test --no-default-features \ No newline at end of file + run: RUST_LOG=info cargo test --no-default-features \ No newline at end of file diff --git a/frontend/.vscode/launch.json b/frontend/.vscode/launch.json index 74249d756e..66fc02b1a1 100644 --- a/frontend/.vscode/launch.json +++ b/frontend/.vscode/launch.json @@ -11,7 +11,7 @@ "type": "dart", "preLaunchTask": "build_flowy_sdk", "env":{ - "RUST_LOG":"info", + "RUST_LOG":"info" }, "cwd": "${workspaceRoot}/app_flowy" }, @@ -22,7 +22,7 @@ "type": "dart", "preLaunchTask": "build_flowy_sdk", "env":{ - "RUST_LOG":"trace", + "RUST_LOG":"trace" }, "cwd": "${workspaceRoot}/app_flowy" }, diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 65f01b6a93..7c82e17ba7 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -45,7 +45,7 @@ FLUTTER_FLOWY_SDK_PATH="app_flowy/packages/flowy_sdk" PROTOBUF_DERIVE_CACHE="../shared-lib/flowy-derive/src/derive_cache/derive_cache.rs" [env.development-mac] -RUST_LOG = "trace" +RUST_LOG = "info" TARGET_OS = "macos" RUST_COMPILE_TARGET = "x86_64-apple-darwin" BUILD_FLAG = "debug" diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index 990aef30b7..2a59cbc80d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; +import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/widgets.dart'; @@ -85,18 +86,31 @@ class _CellCalendar extends StatefulWidget with FlowyOverlayDelegate { required VoidCallback onDismissed, }) async { _CellCalendar.remove(context); - final window = await getWindowInfo(); + final calendar = _CellCalendar(onSelected: onSelected, onDismissed: onDismissed); - const size = Size(460, 400); - FlowyOverlay.of(context).insertWithRect( + // const size = Size(460, 400); + // final window = await getWindowInfo(); + // FlowyOverlay.of(context).insertWithRect( + // widget: OverlayContainer( + // child: calendar, + // constraints: BoxConstraints.loose(const Size(460, 400)), + // ), + // identifier: _CellCalendar.identifier(), + // anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), + // anchorSize: window.frame.size, + // anchorDirection: AnchorDirection.center, + // style: FlowyOverlayStyle(blur: false), + // delegate: calendar, + // ); + + FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: calendar, - constraints: BoxConstraints.loose(const Size(460, 400)), + constraints: BoxConstraints.loose(const Size(300, 320)), ), identifier: _CellCalendar.identifier(), - anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), - anchorSize: window.frame.size, - anchorDirection: AnchorDirection.center, + anchorContext: context, + anchorDirection: AnchorDirection.bottomWithCenterAligned, style: FlowyOverlayStyle(blur: false), delegate: calendar, ); @@ -121,12 +135,32 @@ class _CellCalendarState extends State<_CellCalendar> { @override Widget build(BuildContext context) { + final theme = context.watch(); return TableCalendar( firstDay: kFirstDay, lastDay: kLastDay, focusedDay: _focusedDay, + rowHeight: 40, calendarFormat: _calendarFormat, headerStyle: const HeaderStyle(formatButtonVisible: false), + calendarStyle: CalendarStyle( + selectedDecoration: BoxDecoration( + color: theme.main1, + shape: BoxShape.circle, + ), + todayDecoration: BoxDecoration( + color: theme.shader4, + shape: BoxShape.circle, + ), + selectedTextStyle: TextStyle( + color: theme.surface, + fontSize: 14.0, + ), + todayTextStyle: TextStyle( + color: theme.surface, + fontSize: 14.0, + ), + ), selectedDayPredicate: (day) { return isSameDay(_selectedDay, day); }, diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 93ff98a6f3..9605212726 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -46,4 +46,4 @@ lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file default = [] http_server = [] flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-revision/flowy_unit_test"] -dart = ["lib-infra/dart", "flowy-folder/dart"] \ No newline at end of file +dart = ["lib-infra/dart"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-folder/src/services/app/controller.rs b/frontend/rust-lib/flowy-folder/src/services/app/controller.rs index 8ecb4f79b6..ce8cc321a6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/app/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/app/controller.rs @@ -221,7 +221,7 @@ async fn handle_trash_event( } } -#[tracing::instrument(skip(workspace_id, trash_controller, transaction), err)] +#[tracing::instrument(level = "debug", skip(workspace_id, trash_controller, transaction), err)] fn notify_apps_changed<'a>( workspace_id: &str, trash_controller: Arc, diff --git a/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs index f3f354d517..45034646b0 100644 --- a/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs @@ -36,7 +36,7 @@ pub(crate) async fn delete_app_handler( Ok(()) } -#[tracing::instrument(skip(data, controller))] +#[tracing::instrument(level = "debug", skip(data, controller))] pub(crate) async fn update_app_handler( data: Data, controller: AppData>, @@ -46,7 +46,7 @@ pub(crate) async fn update_app_handler( Ok(()) } -#[tracing::instrument(skip(data, app_controller, view_controller))] +#[tracing::instrument(level = "debug", skip(data, app_controller, view_controller))] pub(crate) async fn read_app_handler( data: Data, app_controller: AppData>, diff --git a/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs b/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs index c4b433bc51..cdbabc1320 100644 --- a/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs @@ -274,7 +274,7 @@ impl TrashController { } } -#[tracing::instrument(skip(repeated_trash), fields(n_trash))] +#[tracing::instrument(level = "debug", skip(repeated_trash), fields(n_trash))] fn notify_trash_changed(repeated_trash: RepeatedTrash) { tracing::Span::current().record("n_trash", &repeated_trash.len()); send_anonymous_dart_notification(FolderNotification::TrashUpdated) diff --git a/frontend/rust-lib/flowy-folder/src/services/trash/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/trash/event_handler.rs index 1f7257a043..b1853faaf5 100644 --- a/frontend/rust-lib/flowy-folder/src/services/trash/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/trash/event_handler.rs @@ -6,7 +6,7 @@ use crate::{ use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; -#[tracing::instrument(skip(controller), err)] +#[tracing::instrument(level = "debug", skip(controller), err)] pub(crate) async fn read_trash_handler( controller: AppData>, ) -> DataResult { @@ -14,7 +14,7 @@ pub(crate) async fn read_trash_handler( data_result(repeated_trash) } -#[tracing::instrument(skip(identifier, controller), err)] +#[tracing::instrument(level = "debug", skip(identifier, controller), err)] pub(crate) async fn putback_trash_handler( identifier: Data, controller: AppData>, @@ -23,7 +23,7 @@ pub(crate) async fn putback_trash_handler( Ok(()) } -#[tracing::instrument(skip(identifiers, controller), err)] +#[tracing::instrument(level = "debug", skip(identifiers, controller), err)] pub(crate) async fn delete_trash_handler( identifiers: Data, controller: AppData>, @@ -32,13 +32,13 @@ pub(crate) async fn delete_trash_handler( Ok(()) } -#[tracing::instrument(skip(controller), err)] +#[tracing::instrument(level = "debug", skip(controller), err)] pub(crate) async fn restore_all_trash_handler(controller: AppData>) -> Result<(), FlowyError> { let _ = controller.restore_all_trash().await?; Ok(()) } -#[tracing::instrument(skip(controller), err)] +#[tracing::instrument(level = "debug", skip(controller), err)] pub(crate) async fn delete_all_trash_handler(controller: AppData>) -> Result<(), FlowyError> { let _ = controller.delete_all_trash().await?; Ok(()) 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 2a8fb7224e..c48203b74b 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -100,7 +100,7 @@ impl ViewController { .await } - #[tracing::instrument(skip(self, view_id), fields(view_id = %view_id.value), err)] + #[tracing::instrument(level = "debug", skip(self, view_id), fields(view_id = %view_id.value), err)] pub(crate) async fn read_view(&self, view_id: ViewId) -> Result { let view = self .persistence @@ -224,14 +224,14 @@ impl ViewController { } impl ViewController { - #[tracing::instrument(skip(self), err)] + #[tracing::instrument(level = "debug", skip(self), err)] async fn create_view_on_server(&self, params: CreateViewParams) -> Result { let token = self.user.token()?; let view = self.cloud_service.create_view(&token, params).await?; Ok(view) } - #[tracing::instrument(skip(self), err)] + #[tracing::instrument(level = "debug", skip(self), err)] fn update_view_on_server(&self, params: UpdateViewParams) -> Result<(), FlowyError> { let token = self.user.token()?; let server = self.cloud_service.clone(); @@ -247,7 +247,7 @@ impl ViewController { Ok(()) } - #[tracing::instrument(skip(self), err)] + #[tracing::instrument(level = "debug", skip(self), err)] fn read_view_on_server(&self, params: ViewId) -> Result<(), FlowyError> { let token = self.user.token()?; let server = self.cloud_service.clone(); @@ -424,7 +424,12 @@ fn notify_dart(view: View, notification: FolderNotification) { send_dart_notification(&view.id, notification).payload(view).send(); } -#[tracing::instrument(skip(belong_to_id, trash_controller, transaction), fields(view_count), err)] +#[tracing::instrument( + level = "debug", + skip(belong_to_id, trash_controller, transaction), + fields(view_count), + err +)] fn notify_views_changed<'a>( belong_to_id: &str, trash_controller: Arc, 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 3468fd62a2..4f692d723d 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 @@ -33,7 +33,7 @@ pub(crate) async fn read_view_handler( data_result(view) } -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(level = "debug", skip(data, controller), err)] pub(crate) async fn update_view_handler( data: Data, controller: AppData>, @@ -83,7 +83,7 @@ pub(crate) async fn close_view_handler( Ok(()) } -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(level = "debug", skip(data, controller), err)] pub(crate) async fn duplicate_view_handler( data: Data, controller: AppData>, 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 02034750ee..d274e42f7f 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 @@ -13,7 +13,7 @@ use flowy_folder_data_model::entities::{ use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(level = "debug", skip(data, controller), err)] pub(crate) async fn create_workspace_handler( data: Data, controller: AppData>, @@ -24,7 +24,7 @@ pub(crate) async fn create_workspace_handler( data_result(detail) } -#[tracing::instrument(skip(controller), err)] +#[tracing::instrument(level = "debug", skip(controller), err)] pub(crate) async fn read_workspace_apps_handler( controller: AppData>, ) -> DataResult { @@ -32,7 +32,7 @@ pub(crate) async fn read_workspace_apps_handler( data_result(repeated_app) } -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(level = "debug", skip(data, controller), err)] pub(crate) async fn open_workspace_handler( data: Data, controller: AppData>, @@ -42,7 +42,7 @@ pub(crate) async fn open_workspace_handler( data_result(workspaces) } -#[tracing::instrument(skip(data, folder), err)] +#[tracing::instrument(level = "debug", skip(data, folder), err)] pub(crate) async fn read_workspaces_handler( data: Data, folder: AppData>, @@ -69,7 +69,7 @@ pub(crate) async fn read_workspaces_handler( data_result(workspaces) } -#[tracing::instrument(skip(folder), err)] +#[tracing::instrument(level = "debug", skip(folder), err)] pub async fn read_cur_workspace_handler( folder: AppData>, ) -> DataResult { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 0ad2d9585a..c4ef4614f1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -197,10 +197,11 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { - use crate::services::field::DateTypeOption; use crate::services::field::FieldBuilder; - use crate::services::row::CellDataOperation; + use crate::services::field::{DateFormat, DateTypeOption, TimeFormat}; + use crate::services::row::{CellDataOperation, TypeOptionCellData}; use flowy_grid_data_model::entities::FieldType; + use strum::IntoEnumIterator; #[test] fn date_description_invalid_input_test() { @@ -221,33 +222,35 @@ mod tests { match date_format { DateFormat::Friendly => { assert_eq!( - "Mar 14,2022 17:56".to_owned(), + "Mar 14,2022".to_owned(), type_option.decode_cell_data(data("1647251762"), &field_meta) ); assert_eq!( - "Mar 14,2022 17:56".to_owned(), + // "Mar 14,2022".to_owned(), + "".to_owned(), type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) ); } DateFormat::US => { assert_eq!( - "2022/03/14 17:56".to_owned(), + "2022/03/14".to_owned(), type_option.decode_cell_data(data("1647251762"), &field_meta) ); assert_eq!( - "2022/03/14 17:56".to_owned(), + // "2022/03/14".to_owned(), + "".to_owned(), type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) ); } DateFormat::ISO => { assert_eq!( - "2022-03-14 17:56".to_owned(), + "2022-03-14".to_owned(), type_option.decode_cell_data(data("1647251762"), &field_meta) ); } DateFormat::Local => { assert_eq!( - "2022/03/14 17:56".to_owned(), + "2022/03/14".to_owned(), type_option.decode_cell_data(data("1647251762"), &field_meta) ); } @@ -263,22 +266,16 @@ mod tests { type_option.time_format = time_format; match time_format { TimeFormat::TwentyFourHour => { + assert_eq!("Mar 14,2022".to_owned(), type_option.today_from_timestamp(1647251762)); assert_eq!( - "Mar 14,2022 17:56".to_owned(), - type_option.today_from_timestamp(1647251762) - ); - assert_eq!( - "Mar 14,2022 17:56".to_owned(), + "Mar 14,2022".to_owned(), type_option.decode_cell_data(data("1647251762"), &field_meta) ); } TimeFormat::TwelveHour => { + assert_eq!("Mar 14,2022".to_owned(), type_option.today_from_timestamp(1647251762)); assert_eq!( - "Mar 14,2022 05:56:02 PM".to_owned(), - type_option.today_from_timestamp(1647251762) - ); - assert_eq!( - "Mar 14,2022 05:56:02 PM".to_owned(), + "Mar 14,2022".to_owned(), type_option.decode_cell_data(data("1647251762"), &field_meta) ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 38ea9d5e78..08e61a57e9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -65,53 +65,57 @@ impl CellDataOperation for RichTextTypeOption { #[cfg(test)] mod tests { + use crate::services::field::FieldBuilder; + use crate::services::field::*; + use crate::services::row::{CellDataOperation, TypeOptionCellData}; + use flowy_grid_data_model::entities::FieldType; - // #[test] - // fn text_description_test() { - // let type_option = RichTextTypeOption::default(); - // - // // date - // let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); - // let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); - // assert_eq!( - // type_option.decode_cell_data(data, &date_time_field_meta), - // "Mar 14,2022 17:56".to_owned() - // ); - // - // // Single select - // let done_option = SelectOption::new("Done"); - // let done_option_id = done_option.id.clone(); - // let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); - // let single_select_field_meta = FieldBuilder::new(single_select).build(); - // let cell_data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); - // assert_eq!( - // type_option.decode_cell_data(cell_data, &single_select_field_meta), - // "Done".to_owned() - // ); - // - // // Multiple select - // let google_option = SelectOption::new("Google"); - // let facebook_option = SelectOption::new("Facebook"); - // let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); - // let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).cell_data(); - // let multi_select = MultiSelectTypeOptionBuilder::default() - // .option(google_option) - // .option(facebook_option); - // let multi_select_field_meta = FieldBuilder::new(multi_select).build(); - // let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta); - // let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap(); - // assert_eq!( - // type_option.decode_cell_data(cell_data, &multi_select_field_meta), - // "Google,Facebook".to_owned() - // ); - // - // //Number - // let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD); - // let number_field_meta = FieldBuilder::new(number).build(); - // let data = TypeOptionCellData::new("18443", FieldType::Number).json(); - // assert_eq!( - // type_option.decode_cell_data(data, &number_field_meta), - // "$18,443".to_owned() - // ); - // } + #[test] + fn text_description_test() { + let type_option = RichTextTypeOption::default(); + + // date + let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); + let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); + assert_eq!( + type_option.decode_cell_data(data, &date_time_field_meta), + "Mar 14,2022".to_owned() + ); + + // Single select + let done_option = SelectOption::new("Done"); + let done_option_id = done_option.id.clone(); + let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); + let single_select_field_meta = FieldBuilder::new(single_select).build(); + let cell_data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); + assert_eq!( + type_option.decode_cell_data(cell_data, &single_select_field_meta), + "Done".to_owned() + ); + + // Multiple select + let google_option = SelectOption::new("Google"); + let facebook_option = SelectOption::new("Facebook"); + let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); + let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).cell_data(); + let multi_select = MultiSelectTypeOptionBuilder::default() + .option(google_option) + .option(facebook_option); + let multi_select_field_meta = FieldBuilder::new(multi_select).build(); + let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta); + let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap(); + assert_eq!( + type_option.decode_cell_data(cell_data, &multi_select_field_meta), + "Google,Facebook".to_owned() + ); + + //Number + let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD); + let number_field_meta = FieldBuilder::new(number).build(); + let data = TypeOptionCellData::new("18443", FieldType::Number).json(); + assert_eq!( + type_option.decode_cell_data(data, &number_field_meta), + "$18,443".to_owned() + ); + } } diff --git a/frontend/rust-lib/flowy-net/src/handlers/mod.rs b/frontend/rust-lib/flowy-net/src/handlers/mod.rs index bb2f58fb4c..3f77ba3a04 100644 --- a/frontend/rust-lib/flowy-net/src/handlers/mod.rs +++ b/frontend/rust-lib/flowy-net/src/handlers/mod.rs @@ -3,7 +3,7 @@ use flowy_error::FlowyError; use lib_dispatch::prelude::{AppData, Data}; use std::sync::Arc; -#[tracing::instrument(skip(data, ws_manager))] +#[tracing::instrument(level = "debug", skip(data, ws_manager))] pub async fn update_network_ty( data: Data, ws_manager: AppData>, diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 33c94f9f0f..06a140805e 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -55,8 +55,8 @@ impl FlowySDKConfig { } } - pub fn log_filter(mut self, filter: &str) -> Self { - self.log_filter = crate_log_filter(filter.to_owned()); + pub fn log_filter(mut self, level: &str) -> Self { + self.log_filter = crate_log_filter(level.to_owned()); self } } @@ -69,12 +69,12 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("flowy_user={}", level)); filters.push(format!("flowy_text_block={}", level)); filters.push(format!("flowy_grid={}", level)); - filters.push(format!("flowy_collaboration={}", "debug")); + filters.push(format!("flowy_collaboration={}", "info")); filters.push(format!("dart_notify={}", level)); filters.push(format!("lib_ot={}", level)); filters.push(format!("lib_ws={}", level)); filters.push(format!("lib_infra={}", level)); - filters.push(format!("flowy_sync={}", "debug")); + filters.push(format!("flowy_sync={}", level)); filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_database={}", "info")); diff --git a/frontend/rust-lib/flowy-test/src/lib.rs b/frontend/rust-lib/flowy-test/src/lib.rs index 1bd12ff9a1..70159edf19 100644 --- a/frontend/rust-lib/flowy-test/src/lib.rs +++ b/frontend/rust-lib/flowy-test/src/lib.rs @@ -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, &nanoid!(6)).log_filter("trace"); + let config = FlowySDKConfig::new(&root_dir(), server_config, &nanoid!(6)).log_filter("info"); 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-text-block/src/event_handler.rs b/frontend/rust-lib/flowy-text-block/src/event_handler.rs index 4e8b48ae05..183103b73e 100644 --- a/frontend/rust-lib/flowy-text-block/src/event_handler.rs +++ b/frontend/rust-lib/flowy-text-block/src/event_handler.rs @@ -27,7 +27,7 @@ pub(crate) async fn apply_delta_handler( data_result(block_delta) } -#[tracing::instrument(skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn export_handler( data: Data, manager: AppData>, diff --git a/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs b/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs index f9ed7c72ac..f463a0932a 100644 --- a/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs +++ b/frontend/rust-lib/flowy-text-block/tests/editor/mod.rs @@ -13,7 +13,7 @@ use lib_ot::{ use rand::{prelude::*, Rng as WrappedRng}; use std::{sync::Once, time::Duration}; -const LEVEL: &str = "debug"; +const LEVEL: &str = "info"; #[derive(Clone, Debug, Display)] pub enum TestOp { diff --git a/frontend/rust-lib/flowy-user/src/handlers/auth_handler.rs b/frontend/rust-lib/flowy-user/src/handlers/auth_handler.rs index 0285b2a442..b5d667bcbe 100644 --- a/frontend/rust-lib/flowy-user/src/handlers/auth_handler.rs +++ b/frontend/rust-lib/flowy-user/src/handlers/auth_handler.rs @@ -5,7 +5,7 @@ use lib_dispatch::prelude::*; use std::{convert::TryInto, sync::Arc}; // tracing instrument 👉🏻 https://docs.rs/tracing/0.1.26/tracing/attr.instrument.html -#[tracing::instrument(name = "sign_in", skip(data, session), fields(email = %data.email), err)] +#[tracing::instrument(level = "debug", name = "sign_in", skip(data, session), fields(email = %data.email), err)] pub async fn sign_in( data: Data, session: AppData>, @@ -16,6 +16,7 @@ pub async fn sign_in( } #[tracing::instrument( + level = "debug", name = "sign_up", skip(data, session), fields( diff --git a/frontend/rust-lib/flowy-user/src/handlers/user_handler.rs b/frontend/rust-lib/flowy-user/src/handlers/user_handler.rs index 1692faa9ac..a13f7187f7 100644 --- a/frontend/rust-lib/flowy-user/src/handlers/user_handler.rs +++ b/frontend/rust-lib/flowy-user/src/handlers/user_handler.rs @@ -6,31 +6,31 @@ use flowy_user_data_model::entities::{ use lib_dispatch::prelude::*; use std::{convert::TryInto, sync::Arc}; -#[tracing::instrument(skip(session))] +#[tracing::instrument(level = "debug", skip(session))] pub async fn init_user_handler(session: AppData>) -> Result<(), FlowyError> { let _ = session.init_user().await?; Ok(()) } -#[tracing::instrument(skip(session))] +#[tracing::instrument(level = "debug", skip(session))] pub async fn check_user_handler(session: AppData>) -> DataResult { let user_profile = session.check_user().await?; data_result(user_profile) } -#[tracing::instrument(skip(session))] +#[tracing::instrument(level = "debug", skip(session))] pub async fn get_user_profile_handler(session: AppData>) -> DataResult { let user_profile = session.user_profile().await?; data_result(user_profile) } -#[tracing::instrument(name = "sign_out", skip(session))] +#[tracing::instrument(level = "debug", name = "sign_out", skip(session))] pub async fn sign_out(session: AppData>) -> Result<(), FlowyError> { let _ = session.sign_out().await?; Ok(()) } -#[tracing::instrument(name = "update_user", skip(data, session))] +#[tracing::instrument(level = "debug", name = "update_user", skip(data, session))] pub async fn update_user_handler( data: Data, session: AppData>, @@ -42,7 +42,7 @@ pub async fn update_user_handler( const APPEARANCE_SETTING_CACHE_KEY: &str = "appearance_settings"; -#[tracing::instrument(skip(data), err)] +#[tracing::instrument(level = "debug", skip(data), err)] pub async fn set_appearance_setting(data: Data) -> Result<(), FlowyError> { let mut setting = data.into_inner(); if setting.theme.is_empty() { diff --git a/frontend/rust-lib/flowy-user/src/services/database.rs b/frontend/rust-lib/flowy-user/src/services/database.rs index 1229d6fba5..f3ddf48fa5 100644 --- a/frontend/rust-lib/flowy-user/src/services/database.rs +++ b/frontend/rust-lib/flowy-user/src/services/database.rs @@ -27,7 +27,7 @@ impl UserDB { return Err(ErrorCode::UserIdIsEmpty.into()); } - tracing::info!("open user db {}", user_id); + tracing::trace!("open user db {}", user_id); let dir = format!("{}/{}", self.db_dir, user_id); let db = flowy_database::init(&dir).map_err(|e| { log::error!("init user db failed, {:?}, user_id: {}", e, user_id); diff --git a/frontend/rust-lib/lib-log/src/lib.rs b/frontend/rust-lib/lib-log/src/lib.rs index c667f33344..d2e0310906 100644 --- a/frontend/rust-lib/lib-log/src/lib.rs +++ b/frontend/rust-lib/lib-log/src/lib.rs @@ -94,7 +94,7 @@ mod tests { say("hello world"); } - #[tracing::instrument(name = "say")] + #[tracing::instrument(level = "trace", name = "say")] fn say(s: &str) { tracing::info!("{}", s); } From a0553b12555e9eb1c72193358386f0da351cd98e Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 12 Apr 2022 11:52:14 +0800 Subject: [PATCH 145/179] chore: fix warnings --- .../plugins/grid/src/widgets/cell/date_cell.dart | 1 - .../flowy-sync/src/client_grid/grid_block_meta_pad.rs | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index 2a59cbc80d..c5100df969 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -7,7 +7,6 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:table_calendar/table_calendar.dart'; -import 'package:window_size/window_size.dart'; class DateCell extends GridCell { final CellData cellData; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 748495f67e..1a51b1bebb 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -258,7 +258,7 @@ mod tests { assert_eq!(pad.rows.first().unwrap().as_ref(), &row); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); } @@ -272,19 +272,19 @@ mod tests { let change = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":90},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":90},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row_meta(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":157},{"insert":",{\"id\":\"3\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":157},{"insert":",{\"id\":\"3\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); assert_eq!(*pad.rows[0], row_1); From 943b4507ac3c092baa60b1c7216616e366472930 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 12 Apr 2022 15:22:33 +0800 Subject: [PATCH 146/179] chore: config field separate line --- .../grid/field/field_cell_bloc.dart | 4 ++ .../application/grid/field/field_service.dart | 20 ++++----- .../home/menu/app/header/add_button.dart | 4 +- .../home/menu/app/section/item.dart | 2 +- .../plugins/grid/src/grid_page.dart | 4 +- .../cell/selection_cell/selection_editor.dart | 2 +- .../grid/src/widgets/header/field_cell.dart | 41 +++++++++++++++++-- .../grid/src/widgets/header/grid_header.dart | 17 ++++---- .../presentation/widgets/pop_up_action.dart | 2 +- .../lib/style_widget/button.dart | 2 +- .../lib/style_widget/hover.dart | 25 ++++++----- 11 files changed, 79 insertions(+), 44 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart index c7964573d3..1afbded351 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -10,10 +10,12 @@ part 'field_cell_bloc.freezed.dart'; class FieldCellBloc extends Bloc { final FieldListener _fieldListener; + final FieldService _fieldService; FieldCellBloc({ required GridFieldCellContext cellContext, }) : _fieldListener = FieldListener(fieldId: cellContext.field.id), + _fieldService = FieldService(gridId: cellContext.gridId), super(FieldCellState.initial(cellContext)) { on( (event, emit) async { @@ -24,6 +26,7 @@ class FieldCellBloc extends Bloc { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(field: value.field)); }, + updateWidth: (_UpdateWidth value) {}, ); }, ); @@ -50,6 +53,7 @@ class FieldCellBloc extends Bloc { class FieldCellEvent with _$FieldCellEvent { const factory FieldCellEvent.initial() = _InitialCell; const factory FieldCellEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate; + const factory FieldCellEvent.updateWidth(double offset) = _UpdateWidth; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index c058bcd36c..743a441c7d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -1,9 +1,10 @@ import 'package:dartz/dartz.dart'; -import 'package:equatable/equatable.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +part 'field_service.freezed.dart'; class FieldService { final String gridId; @@ -98,17 +99,12 @@ class FieldService { } } -class GridFieldCellContext extends Equatable { - final String gridId; - final Field field; - - const GridFieldCellContext({ - required this.gridId, - required this.field, - }); - - @override - List get props => [field.id]; +@freezed +class GridFieldCellContext with _$GridFieldCellContext { + const factory GridFieldCellContext({ + required String gridId, + required Field field, + }) = _GridFieldCellContext; } abstract class EditFieldContextLoader { diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart index 6df78a67cc..214dc7a198 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart @@ -78,10 +78,10 @@ class CreateItem extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); - final config = HoverDisplayConfig(hoverColor: theme.hover); + final config = HoverStyle(hoverColor: theme.hover); return FlowyHover( - config: config, + style: config, builder: (context, onHover) { return GestureDetector( onTap: () => onSelected(pluginBuilder), diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart index 15a27268c5..290d2bd328 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart @@ -43,7 +43,7 @@ class ViewSectionItem extends StatelessWidget { return InkWell( onTap: () => onSelected(context.read().state.view), child: FlowyHover( - config: HoverDisplayConfig(hoverColor: theme.bg3), + style: HoverStyle(hoverColor: theme.bg3), builder: (_, onHover) => _render(context, onHover, state, theme.iconColor), setSelected: () => state.isEditing || isSelected, ), 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 6f6878c515..50d1913057 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 @@ -100,7 +100,7 @@ class _FlowyGridState extends State { controller: _scrollController.verticalController, slivers: [ _renderToolbar(state.gridId), - _renderGridHeader(state.gridId), + _renderHeader(state.gridId), _renderRows(gridId: state.gridId, context: context), const GridFooter(), ], @@ -126,7 +126,7 @@ class _FlowyGridState extends State { ); } - Widget _renderGridHeader(String gridId) { + Widget _renderHeader(String gridId) { return BlocSelector>( selector: (state) => state.fields, builder: (context, fields) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index feefb552cd..4ebd4407b0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -199,7 +199,7 @@ class _SelectOptionCell extends StatelessWidget { context.read().add(SelectOptionEditorEvent.selectOption(option.id)); }, child: FlowyHover( - config: HoverDisplayConfig(hoverColor: theme.hover), + style: HoverStyle(hoverColor: theme.hover), builder: (_, onHover) { List children = [ SelectOptionTag(option: option, isSelected: isSelected), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index 79e706085f..5d658c693c 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -4,7 +4,9 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_type_extension.dart'; @@ -25,21 +27,52 @@ class GridFieldCell extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final button = FlowyButton( - hoverColor: theme.hover, + hoverColor: theme.shader6, onTap: () => _showActionSheet(context), - rightIcon: svgWidget("editor/details", color: theme.iconColor), + // rightIcon: svgWidget("editor/details", color: theme.iconColor), leftIcon: svgWidget(state.field.fieldType.iconName(), color: theme.iconColor), text: FlowyText.medium(state.field.name, fontSize: 12), padding: GridSize.cellContentInsets, ); + final line = InkWell( + onTap: () {}, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onHorizontalDragCancel: () {}, + onHorizontalDragUpdate: (value) { + Log.info(value.delta); + }, + child: FlowyHover( + style: HoverStyle( + hoverColor: theme.main1, + borderRadius: BorderRadius.zero, + contentMargin: const EdgeInsets.only(left: 5), + ), + builder: (_, onHover) => const SizedBox(width: 2), + ), + ), + ); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); - final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide)); + final decoration = BoxDecoration( + border: Border( + top: borderSide, + right: borderSide, + bottom: borderSide, + )); return Container( width: state.field.width.toDouble(), decoration: decoration, - child: button, + child: ConstrainedBox( + constraints: const BoxConstraints.expand(), + child: Stack( + alignment: Alignment.centerRight, + fit: StackFit.expand, + children: [button, Positioned(top: 0, bottom: 0, right: 0, child: line)], + ), + ), ); }, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 5568f2ef62..b5893fa095 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -72,28 +72,27 @@ class _GridHeaderWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = context.watch(); final cells = fields.map( (field) => GridFieldCell( GridFieldCellContext(gridId: gridId, field: field), ), ); - final row = Row( + return Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - const _HeaderLeading(), + const _CellLeading(), ...cells, - _HeaderTrailing(gridId: gridId), + _CellTrailing(gridId: gridId), ], ); - return Container(height: GridSize.headerHeight, color: theme.surface, child: row); + // return Container(height: GridSize.headerHeight, color: theme.surface, child: row); } } -class _HeaderLeading extends StatelessWidget { - const _HeaderLeading({Key? key}) : super(key: key); +class _CellLeading extends StatelessWidget { + const _CellLeading({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -103,9 +102,9 @@ class _HeaderLeading extends StatelessWidget { } } -class _HeaderTrailing extends StatelessWidget { +class _CellTrailing extends StatelessWidget { final String gridId; - const _HeaderTrailing({required this.gridId, Key? key}) : super(key: key); + const _CellTrailing({required this.gridId, Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart index 5c782d3ece..cc822a6ef9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart @@ -85,7 +85,7 @@ class ActionCell extends StatelessWidget { final theme = context.watch(); return FlowyHover( - config: HoverDisplayConfig(hoverColor: theme.hover), + style: HoverStyle(hoverColor: theme.hover), builder: (context, onHover) { return GestureDetector( behavior: HitTestBehavior.opaque, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 69cddbf2fb..8249bc115b 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -28,7 +28,7 @@ class FlowyButton extends StatelessWidget { return InkWell( onTap: onTap, child: FlowyHover( - config: HoverDisplayConfig(borderRadius: Corners.s6Border, hoverColor: hoverColor), + style: HoverStyle(borderRadius: Corners.s6Border, hoverColor: hoverColor), setSelected: () => isSelected, builder: (context, onHover) => _render(), ), diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index 48a702c2e4..f8caf35b84 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -5,14 +5,14 @@ import 'package:flowy_infra/time/duration.dart'; typedef HoverBuilder = Widget Function(BuildContext context, bool onHover); class FlowyHover extends StatefulWidget { - final HoverDisplayConfig config; + final HoverStyle style; final HoverBuilder builder; final bool Function()? setSelected; const FlowyHover({ Key? key, required this.builder, - required this.config, + required this.style, this.setSelected, }) : super(key: key); @@ -41,7 +41,7 @@ class _FlowyHoverState extends State { if (showHover) { return FlowyHoverContainer( - config: widget.config, + style: widget.style, child: widget.builder(context, _onHover), ); } else { @@ -50,41 +50,44 @@ class _FlowyHoverState extends State { } } -class HoverDisplayConfig { +class HoverStyle { final Color borderColor; final double borderWidth; final Color hoverColor; final BorderRadius borderRadius; + final EdgeInsets contentMargin; - const HoverDisplayConfig( + const HoverStyle( {this.borderColor = Colors.transparent, this.borderWidth = 0, this.borderRadius = const BorderRadius.all(Radius.circular(6)), + this.contentMargin = EdgeInsets.zero, required this.hoverColor}); } class FlowyHoverContainer extends StatelessWidget { - final HoverDisplayConfig config; + final HoverStyle style; final Widget child; const FlowyHoverContainer({ Key? key, required this.child, - required this.config, + required this.style, }) : super(key: key); @override Widget build(BuildContext context) { final hoverBorder = Border.all( - color: config.borderColor, - width: config.borderWidth, + color: style.borderColor, + width: style.borderWidth, ); return Container( + margin: style.contentMargin, decoration: BoxDecoration( border: hoverBorder, - color: config.hoverColor, - borderRadius: config.borderRadius, + color: style.hoverColor, + borderRadius: style.borderRadius, ), child: child, ); From a7074105480c7da3c1d13197714ced0af97860ec Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 12 Apr 2022 21:31:38 +0800 Subject: [PATCH 147/179] chore: format number cell --- .../app_flowy/lib/startup/deps_resolver.dart | 7 -- .../grid/cell_bloc/number_cell_bloc.dart | 49 ++++++++----- .../grid/field/field_cell_bloc.dart | 8 ++- .../grid/field/grid_header_bloc.dart | 72 ------------------- .../workspace/application/grid/prelude.dart | 1 - .../plugins/grid/src/grid_page.dart | 46 ++++++------ .../grid/src/widgets/cell/number_cell.dart | 10 ++- .../grid/src/widgets/footer/grid_footer.dart | 20 +++--- .../grid/src/widgets/header/field_cell.dart | 2 +- .../grid/src/widgets/header/grid_header.dart | 19 ++--- .../scrolling/styled_scrollview.dart | 34 +++++---- 11 files changed, 101 insertions(+), 167 deletions(-) delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index abf6fffd21..5c835ce217 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -156,13 +156,6 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam>( - (gridId, fields) => GridHeaderBloc( - data: GridHeaderData(gridId: gridId, fields: fields), - service: FieldService(gridId: gridId), - ), - ); - getIt.registerFactoryParam( (data, _) => FieldActionSheetBloc( field: data.field, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index 9fe0af2d5d..e61e8f96a6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; @@ -11,12 +12,14 @@ part 'number_cell_bloc.freezed.dart'; class NumberCellBloc extends Bloc { final CellService _service; - final CellListener _listener; + final CellListener _cellListener; + final FieldListener _fieldListener; NumberCellBloc({ required CellData cellData, }) : _service = CellService(), - _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _fieldListener = FieldListener(fieldId: cellData.field.id), super(NumberCellState.initial(cellData)) { on( (event, emit) async { @@ -27,36 +30,36 @@ class NumberCellBloc extends Bloc { didReceiveCellUpdate: (_DidReceiveCellUpdate value) { emit(state.copyWith(content: value.cell.content)); }, - updateCell: (_UpdateCell value) { - _updateCellValue(value, emit); + updateCell: (_UpdateCell value) async { + await _updateCellValue(value, emit); }, ); }, ); } - void _updateCellValue(_UpdateCell value, Emitter emit) { - final number = num.tryParse(value.text); - if (number == null) { - emit(state.copyWith(content: "")); - } else { - _service.updateCell( - gridId: state.cellData.gridId, - fieldId: state.cellData.field.id, - rowId: state.cellData.rowId, - data: value.text, - ); - } + Future _updateCellValue(_UpdateCell value, Emitter emit) async { + final result = await _service.updateCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + data: value.text, + ); + result.fold( + (field) => _getCellData(), + (err) => Log.error(err), + ); } @override Future close() async { - await _listener.stop(); + await _cellListener.stop(); + await _fieldListener.stop(); return super.close(); } void _startListening() { - _listener.updateCellNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier.addPublishListener((result) { result.fold( (notificationData) async { await _getCellData(); @@ -64,7 +67,15 @@ class NumberCellBloc extends Bloc { (err) => Log.error(err), ); }); - _listener.start(); + _cellListener.start(); + + _fieldListener.updateFieldNotifier.addPublishListener((result) { + result.fold( + (field) => _getCellData(), + (err) => Log.error(err), + ); + }); + _fieldListener.start(); } Future _getCellData() async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart index 1afbded351..376b98f19a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -26,7 +26,13 @@ class FieldCellBloc extends Bloc { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(field: value.field)); }, - updateWidth: (_UpdateWidth value) {}, + updateWidth: (_UpdateWidth value) { + final defaultWidth = state.field.width.toDouble(); + final width = defaultWidth + value.offset; + if (width > defaultWidth && width < 300) { + _fieldService.updateField(fieldId: state.field.id, width: width); + } + }, ); }, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart deleted file mode 100644 index 4145e23804..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:app_flowy/workspace/application/grid/data.dart'; -import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; -import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'field_service.dart'; - -part 'grid_header_bloc.freezed.dart'; - -class GridHeaderBloc extends Bloc { - final FieldService service; - final GridFieldsListener _fieldListener; - - GridHeaderBloc({ - required GridHeaderData data, - required this.service, - }) : _fieldListener = GridFieldsListener(gridId: data.gridId), - super(GridHeaderState.initial(data.fields)) { - on( - (event, emit) async { - await event.map( - initial: (_InitialHeader value) async { - _startListening(); - }, - createField: (_CreateField value) {}, - insertField: (_InsertField value) {}, - didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - value.fields.retainWhere((field) => field.visibility); - emit(state.copyWith(fields: value.fields)); - }, - ); - }, - ); - } - - Future _startListening() async { - _fieldListener.updateFieldsNotifier.addPublishListener((result) { - result.fold( - (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), - (err) => Log.error(err), - ); - }); - - _fieldListener.start(); - } - - @override - Future close() async { - await _fieldListener.stop(); - return super.close(); - } -} - -@freezed -class GridHeaderEvent with _$GridHeaderEvent { - const factory GridHeaderEvent.initial() = _InitialHeader; - const factory GridHeaderEvent.createField() = _CreateField; - const factory GridHeaderEvent.insertField({required bool onLeft}) = _InsertField; - const factory GridHeaderEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; -} - -@freezed -class GridHeaderState with _$GridHeaderState { - const factory GridHeaderState({required List fields}) = _GridHeaderState; - - factory GridHeaderState.initial(List fields) { - fields.retainWhere((field) => field.visibility); - return GridHeaderState(fields: fields); - } -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index a795e23fb2..3fd24f8785 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -6,7 +6,6 @@ export 'data.dart'; // Field export 'field/field_service.dart'; -export 'field/grid_header_bloc.dart'; export 'field/field_action_sheet_bloc.dart'; export 'field/field_editor_bloc.dart'; export 'field/field_switch_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 50d1913057..40b282e717 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 @@ -85,7 +85,7 @@ class _FlowyGridState extends State { @override Widget build(BuildContext context) { return BlocBuilder( - buildWhen: (previous, current) => previous.fields != current.fields, + buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { if (state.fields.isEmpty) { return const Center(child: CircularProgressIndicator.adaptive()); @@ -99,10 +99,10 @@ class _FlowyGridState extends State { physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ - _renderToolbar(state.gridId), - _renderHeader(state.gridId), - _renderRows(gridId: state.gridId, context: context), - const GridFooter(), + const _GridToolbarAdaptor(), + GridHeader(gridId: state.gridId, fields: List.from(state.fields)), + _GridRows(), + const SliverToBoxAdapter(child: GridFooter()), ], ), ), @@ -125,33 +125,35 @@ class _FlowyGridState extends State { ), ); } +} - Widget _renderHeader(String gridId) { - return BlocSelector>( - selector: (state) => state.fields, - builder: (context, fields) { - return GridHeader(gridId: gridId, fields: List.from(fields)); - }, - ); - } +class _GridToolbarAdaptor extends StatelessWidget { + const _GridToolbarAdaptor({Key? key}) : super(key: key); - Widget _renderToolbar(String gridId) { - return BlocSelector>( - selector: (state) => state.fields, - builder: (context, fields) { - final toolbarContext = GridToolbarContext( - gridId: gridId, - fields: fields, + @override + Widget build(BuildContext context) { + return BlocSelector( + selector: (state) { + return GridToolbarContext( + gridId: state.gridId, + fields: state.fields, ); - + }, + builder: (context, toolbarContext) { return SliverToBoxAdapter( child: GridToolbar(toolbarContext: toolbarContext), ); }, ); } +} - Widget _renderRows({required String gridId, required BuildContext context}) { +class _GridRows extends StatelessWidget { + final _key = GlobalKey(); + _GridRows({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { return BlocConsumer( listener: (context, state) { state.listState.map( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index fc31340c9f..cd4db24c7a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -26,7 +26,7 @@ class _NumberCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellData); + _cellBloc = getIt(param1: widget.cellData)..add(const NumberCellEvent.initial()); _controller = TextEditingController(text: _cellBloc.state.content); _focusNode = CellFocusNode(); super.initState(); @@ -48,7 +48,6 @@ class _NumberCellState extends State { return TextField( controller: _controller, focusNode: _focusNode, - onChanged: (value) => focusChanged(), onEditingComplete: () => _focusNode.unfocus(), maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), @@ -76,7 +75,12 @@ class _NumberCellState extends State { _delayOperation?.cancel(); _delayOperation = Timer(const Duration(milliseconds: 300), () { if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) { - _cellBloc.add(NumberCellEvent.updateCell(_controller.text)); + final number = num.tryParse(_controller.text); + if (number != null) { + _cellBloc.add(NumberCellEvent.updateCell(_controller.text)); + } else { + _controller.text = ""; + } } }); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 8d9719ae75..35d9ee1378 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -12,17 +12,15 @@ class GridFooter extends StatelessWidget { @override Widget build(BuildContext context) { - return SliverToBoxAdapter( - child: SizedBox( - height: GridSize.footerHeight, - child: Padding( - padding: GridSize.headerContentInsets, - child: Row( - children: [ - SizedBox(width: GridSize.leadingHeaderPadding), - const SizedBox(width: 120, child: _AddRowButton()), - ], - ), + return SizedBox( + height: GridSize.footerHeight, + child: Padding( + padding: GridSize.headerContentInsets, + child: Row( + children: [ + SizedBox(width: GridSize.leadingHeaderPadding), + const SizedBox(width: 120, child: _AddRowButton()), + ], ), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index 5d658c693c..83fcade362 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -41,7 +41,7 @@ class GridFieldCell extends StatelessWidget { behavior: HitTestBehavior.opaque, onHorizontalDragCancel: () {}, onHorizontalDragUpdate: (value) { - Log.info(value.delta); + context.read().add(FieldCellEvent.updateWidth(value.delta.dx)); }, child: FlowyHover( style: HoverStyle( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index b5893fa095..44730f703d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -19,21 +19,10 @@ class GridHeader extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) { - final bloc = getIt(param1: gridId, param2: fields); - bloc.add(const GridHeaderEvent.initial()); - return bloc; - }, - child: BlocBuilder( - builder: (context, state) { - return SliverPersistentHeader( - delegate: _GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)), - floating: true, - pinned: true, - ); - }, - ), + return SliverPersistentHeader( + delegate: _GridHeaderDelegate(gridId: gridId, fields: List.from(fields)), + floating: true, + pinned: true, ); } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart index ed960a1c12..da316685dd 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/scrolling/styled_scrollview.dart @@ -74,21 +74,21 @@ class _StyledSingleChildScrollViewState extends State slivers; + final double barSize; const StyledCustomScrollView({ Key? key, - this.contentSize, this.axis = Axis.vertical, this.trackColor, this.handleColor, - this.controller, + this.verticalController, this.slivers = const [], + this.barSize = 12, }) : super(key: key); @override @@ -96,17 +96,17 @@ class StyledCustomScrollView extends StatefulWidget { } class _StyledCustomScrollViewState extends State { - late ScrollController scrollController; + late ScrollController controller; @override void initState() { - scrollController = widget.controller ?? ScrollController(); + controller = widget.verticalController ?? ScrollController(); + super.initState(); } @override void dispose() { - scrollController.dispose(); super.dispose(); } @@ -120,19 +120,23 @@ class _StyledCustomScrollViewState extends State { @override Widget build(BuildContext context) { - return ScrollbarListStack( - contentSize: widget.contentSize, - axis: widget.axis, - controller: scrollController, - barSize: 12, - trackColor: widget.trackColor, - handleColor: widget.handleColor, + var child = ScrollConfiguration( + behavior: const ScrollBehavior().copyWith(scrollbars: false), child: CustomScrollView( scrollDirection: widget.axis, physics: StyledScrollPhysics(), - controller: scrollController, + controller: controller, slivers: widget.slivers, ), ); + + return ScrollbarListStack( + axis: widget.axis, + controller: controller, + barSize: widget.barSize, + trackColor: widget.trackColor, + handleColor: widget.handleColor, + child: child, + ); } } From b0e07c952ee49ca08d3add5f14c4c8a3895ee33e Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 13 Apr 2022 10:47:07 +0800 Subject: [PATCH 148/179] chore: fixed grid toolbar --- .../grid/cell_bloc/date_cell_bloc.dart | 11 +- .../application/grid/field/field_service.dart | 9 ++ .../plugins/grid/src/grid_page.dart | 125 +++++++++++------- .../grid/src/widgets/cell/date_cell.dart | 18 ++- .../grid/src/widgets/footer/grid_footer.dart | 24 +--- .../grid/src/widgets/header/grid_header.dart | 67 +++------- 6 files changed, 135 insertions(+), 119 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index 8d46b7e659..ff8d7d012e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dar import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell, Field; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -35,6 +35,10 @@ class DateCellBloc extends Bloc { content: value.cell.content, )); }, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + emit(state.copyWith(field: value.field)); + _loadCellData(); + }, ); }, ); @@ -58,7 +62,7 @@ class DateCellBloc extends Bloc { _fieldListener.updateFieldNotifier.addPublishListener((result) { result.fold( - (field) => _loadCellData(), + (field) => add(DateCellEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); }); @@ -97,6 +101,7 @@ class DateCellEvent with _$DateCellEvent { const factory DateCellEvent.initial() = _InitialCell; const factory DateCellEvent.selectDay(DateTime day) = _SelectDay; const factory DateCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; + const factory DateCellEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate; } @freezed @@ -104,11 +109,13 @@ class DateCellState with _$DateCellState { const factory DateCellState({ required CellData cellData, required String content, + required Field field, DateTime? selectedDay, }) = _DateCellState; factory DateCellState.initial(CellData cellData) => DateCellState( cellData: cellData, + field: cellData.field, content: cellData.cell?.content ?? "", ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 743a441c7d..e1bed697c8 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -20,6 +20,15 @@ class FieldService { return GridEventSwitchToField(payload).send(); } + Future> getEditFieldContext(String fieldId, FieldType fieldType) { + final payload = GetEditFieldContextPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..fieldType = fieldType; + + return GridEventGetEditFieldContext(payload).send(); + } + Future> updateField({ required String fieldId, String? name, 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 40b282e717..804ffff685 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 @@ -40,7 +40,7 @@ class _GridPageState extends State { return state.loadingState.map( loading: (_) => const Center(child: CircularProgressIndicator.adaptive()), finish: (result) => result.successOrFail.fold( - (_) => const FlowyGrid(), + (_) => FlowyGrid(), (err) => FlowyErrorPage(err.toString()), ), ); @@ -65,64 +65,61 @@ class _GridPageState extends State { } } -class FlowyGrid extends StatefulWidget { - const FlowyGrid({Key? key}) : super(key: key); - - @override - _FlowyGridState createState() => _FlowyGridState(); -} - -class _FlowyGridState extends State { +class FlowyGrid extends StatelessWidget { final _scrollController = GridScrollController(); - final _key = GlobalKey(); - - @override - void dispose() { - _scrollController.dispose(); - super.dispose(); - } + FlowyGrid({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocBuilder( buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { - if (state.fields.isEmpty) { - return const Center(child: CircularProgressIndicator.adaptive()); - } - - final child = SizedBox( - width: GridLayout.headerWidth(state.fields), - child: ScrollConfiguration( - behavior: const ScrollBehavior().copyWith(scrollbars: false), - child: CustomScrollView( - physics: StyledScrollPhysics(), - controller: _scrollController.verticalController, - slivers: [ - const _GridToolbarAdaptor(), - GridHeader(gridId: state.gridId, fields: List.from(state.fields)), - _GridRows(), - const SliverToBoxAdapter(child: GridFooter()), - ], - ), - ), + final child = _wrapScrollView( + state.fields, + [ + _GridHeader(gridId: state.gridId, fields: List.from(state.fields)), + _GridRows(), + const _GridFooter(), + ], ); - return _wrapScrollbar(child); + return Column(children: [ + const _GridToolbarAdaptor(), + Flexible(child: child), + ]); }, ); } - Widget _wrapScrollbar(Widget child) { + Widget _wrapScrollView( + List fields, + List slivers, + ) { + final verticalScrollView = ScrollConfiguration( + behavior: const ScrollBehavior().copyWith(scrollbars: false), + child: CustomScrollView( + physics: StyledScrollPhysics(), + controller: _scrollController.verticalController, + slivers: slivers, + ), + ); + + final sizedVerticalScrollView = SizedBox( + width: GridLayout.headerWidth(fields), + child: verticalScrollView, + ); + + final horizontalScrollView = StyledSingleChildScrollView( + controller: _scrollController.horizontalController, + axis: Axis.horizontal, + child: sizedVerticalScrollView, + ); + return ScrollbarListStack( axis: Axis.vertical, controller: _scrollController.verticalController, barSize: GridSize.scrollBarSize, - child: StyledSingleChildScrollView( - controller: _scrollController.horizontalController, - axis: Axis.horizontal, - child: child, - ), + child: horizontalScrollView, ); } } @@ -140,14 +137,27 @@ class _GridToolbarAdaptor extends StatelessWidget { ); }, builder: (context, toolbarContext) { - return SliverToBoxAdapter( - child: GridToolbar(toolbarContext: toolbarContext), - ); + return GridToolbar(toolbarContext: toolbarContext); }, ); } } +class _GridHeader extends StatelessWidget { + final String gridId; + final List fields; + const _GridHeader({Key? key, required this.gridId, required this.fields}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SliverPersistentHeader( + delegate: GridHeaderSliverAdaptor(gridId: gridId, fields: List.from(fields)), + floating: true, + pinned: true, + ); + } +} + class _GridRows extends StatelessWidget { final _key = GlobalKey(); _GridRows({Key? key}) : super(key: key); @@ -191,3 +201,28 @@ class _GridRows extends StatelessWidget { ); } } + +class _GridFooter extends StatelessWidget { + const _GridFooter({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SliverPadding( + padding: const EdgeInsets.only(bottom: 200), + sliver: SliverToBoxAdapter( + child: SizedBox( + height: GridSize.footerHeight, + child: Padding( + padding: GridSize.headerContentInsets, + child: Row( + children: [ + SizedBox(width: GridSize.leadingHeaderPadding), + const SizedBox(width: 120, child: GridAddRowButton()), + ], + ), + ), + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index c5100df969..b913a09e4e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -74,7 +74,13 @@ final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day); class _CellCalendar extends StatefulWidget with FlowyOverlayDelegate { final void Function(DateTime) onSelected; final VoidCallback onDismissed; - const _CellCalendar({required this.onSelected, required this.onDismissed, Key? key}) : super(key: key); + final bool includeTime; + const _CellCalendar({ + required this.onSelected, + required this.onDismissed, + required this.includeTime, + Key? key, + }) : super(key: key); @override State<_CellCalendar> createState() => _CellCalendarState(); @@ -86,7 +92,11 @@ class _CellCalendar extends StatefulWidget with FlowyOverlayDelegate { }) async { _CellCalendar.remove(context); - final calendar = _CellCalendar(onSelected: onSelected, onDismissed: onDismissed); + final calendar = _CellCalendar( + onSelected: onSelected, + onDismissed: onDismissed, + includeTime: false, + ); // const size = Size(460, 400); // final window = await getWindowInfo(); // FlowyOverlay.of(context).insertWithRect( @@ -105,11 +115,11 @@ class _CellCalendar extends StatefulWidget with FlowyOverlayDelegate { FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( child: calendar, - constraints: BoxConstraints.loose(const Size(300, 320)), + constraints: BoxConstraints.tight(const Size(320, 320)), ), identifier: _CellCalendar.identifier(), anchorContext: context, - anchorDirection: AnchorDirection.bottomWithCenterAligned, + anchorDirection: AnchorDirection.leftWithCenterAligned, style: FlowyOverlayStyle(blur: false), delegate: calendar, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 35d9ee1378..a99e87f5fa 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -7,28 +7,8 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class GridFooter extends StatelessWidget { - const GridFooter({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: GridSize.footerHeight, - child: Padding( - padding: GridSize.headerContentInsets, - child: Row( - children: [ - SizedBox(width: GridSize.leadingHeaderPadding), - const SizedBox(width: 120, child: _AddRowButton()), - ], - ), - ), - ); - } -} - -class _AddRowButton extends StatelessWidget { - const _AddRowButton({Key? key}) : super(key: key); +class GridAddRowButton extends StatelessWidget { + const GridAddRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 44730f703d..c387ecd4e2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -12,30 +12,32 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_editor.dart'; import 'field_cell.dart'; -class GridHeader extends StatelessWidget { - final String gridId; - final List fields; - const GridHeader({Key? key, required this.gridId, required this.fields}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SliverPersistentHeader( - delegate: _GridHeaderDelegate(gridId: gridId, fields: List.from(fields)), - floating: true, - pinned: true, - ); - } -} - -class _GridHeaderDelegate extends SliverPersistentHeaderDelegate { +class GridHeaderSliverAdaptor extends SliverPersistentHeaderDelegate { final String gridId; final List fields; - _GridHeaderDelegate({required this.gridId, required this.fields}); + GridHeaderSliverAdaptor({required this.gridId, required this.fields}); @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return _GridHeaderWidget(gridId: gridId, fields: fields, key: ObjectKey(fields)); + final cells = fields.map( + (field) => GridFieldCell( + GridFieldCellContext(gridId: gridId, field: field), + ), + ); + + return Container( + color: Colors.white, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _CellLeading(), + ...cells, + _CellTrailing(gridId: gridId), + ], + key: ObjectKey(fields), + ), + ); } @override @@ -46,40 +48,13 @@ class _GridHeaderDelegate extends SliverPersistentHeaderDelegate { @override bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { - if (oldDelegate is _GridHeaderDelegate) { + if (oldDelegate is GridHeaderSliverAdaptor) { return fields.length != oldDelegate.fields.length; } return true; } } -class _GridHeaderWidget extends StatelessWidget { - final String gridId; - final List fields; - - const _GridHeaderWidget({required this.gridId, required this.fields, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final cells = fields.map( - (field) => GridFieldCell( - GridFieldCellContext(gridId: gridId, field: field), - ), - ); - - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _CellLeading(), - ...cells, - _CellTrailing(gridId: gridId), - ], - ); - - // return Container(height: GridSize.headerHeight, color: theme.surface, child: row); - } -} - class _CellLeading extends StatelessWidget { const _CellLeading({Key? key}) : super(key: key); From 2fa6adeee633942a6f3c0b29db114835feff4d97 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 13 Apr 2022 14:24:54 +0800 Subject: [PATCH 149/179] chore: move field --- .../application/grid/grid_listener.dart | 5 +- .../grid/setting/property_bloc.dart | 4 + .../src/widgets/toolbar/grid_property.dart | 16 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../flowy-grid-data-model/grid.pb.dart | 129 ++++- .../flowy-grid-data-model/grid.pbenum.dart | 15 + .../flowy-grid-data-model/grid.pbjson.dart | 35 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 2 + .../protobuf/flowy-grid/event_map.pbjson.dart | 3 +- frontend/app_flowy/pubspec.lock | 7 + frontend/app_flowy/pubspec.yaml | 1 + .../rust-lib/flowy-grid/src/event_handler.rs | 11 + frontend/rust-lib/flowy-grid/src/event_map.rs | 9 +- .../src/protobuf/model/event_map.rs | 17 +- .../src/protobuf/proto/event_map.proto | 1 + .../src/services/block_meta_manager.rs | 14 +- .../flowy-grid/src/services/grid_editor.rs | 18 + .../src/entities/grid.rs | 65 ++- .../src/protobuf/model/grid.rs | 449 ++++++++++++++++-- .../src/protobuf/proto/grid.proto | 13 +- 20 files changed, 730 insertions(+), 101 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index f36a630e1a..862cd95d74 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -9,8 +9,7 @@ import 'package:app_flowy/core/notification_helper.dart'; class GridListener { final String gridId; - PublishNotifier, FlowyError>> rowsUpdateNotifier = - PublishNotifier(comparable: null); + PublishNotifier, FlowyError>> rowsUpdateNotifier = PublishNotifier(comparable: null); GridNotificationListener? _listener; GridListener({required this.gridId}); @@ -26,7 +25,7 @@ class GridListener { switch (ty) { case GridNotification.DidUpdateGridBlock: result.fold( - (payload) => rowsUpdateNotifier.value = left([GridBlockOrderChangeset.fromBuffer(payload)]), + (payload) => rowsUpdateNotifier.value = left([GridRowsChangeset.fromBuffer(payload)]), (error) => rowsUpdateNotifier.value = right(error), ); break; diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index ab618b0fa9..66de503321 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -32,6 +32,9 @@ class GridPropertyBloc extends Bloc { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(fields: value.fields)); }, + moveField: (_MoveField value) { + // + }, ); }, ); @@ -61,6 +64,7 @@ class GridPropertyEvent with _$GridPropertyEvent { const factory GridPropertyEvent.initial() = _Initial; const factory GridPropertyEvent.setFieldVisibility(String fieldId, bool visibility) = _SetFieldVisibility; const factory GridPropertyEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; + const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) = _MoveField; } @freezed diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index a34682d204..0a9cddedd5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -46,20 +46,16 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { getIt(param1: gridId, param2: fields)..add(const GridPropertyEvent.initial()), child: BlocBuilder( builder: (context, state) { - final cells = state.fields.map((field) { - return _GridPropertyCell(gridId: gridId, field: field); + final children = state.fields.map((field) { + return _GridPropertyCell(gridId: gridId, field: field, key: ValueKey(field.id)); }).toList(); - return ListView.separated( + return ReorderableListView( shrinkWrap: true, - controller: ScrollController(), - separatorBuilder: (context, index) { - return VSpace(GridSize.typeOptionSeparatorHeight); - }, - itemCount: cells.length, - itemBuilder: (BuildContext context, int index) { - return cells[index]; + onReorder: (int oldIndex, int newIndex) { + context.read().add(GridPropertyEvent.moveField(oldIndex, newIndex)); }, + children: children, ); }, ), 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 a8fd9add65..33925ca955 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 @@ -154,6 +154,23 @@ class GridEventGetEditFieldContext { } } +class GridEventMoveItem { + MoveItemPayload request; + GridEventMoveItem(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.MoveItem.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventNewSelectOption { SelectOptionName request; GridEventNewSelectOption(this.request); 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 fac1ee178a..1452679e63 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 @@ -857,8 +857,8 @@ class GridBlockOrder extends $pb.GeneratedMessage { $core.List get rowOrders => $_getList(1); } -class GridBlockOrderChangeset extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrderChangeset', createEmptyInstance: create) +class GridRowsChangeset extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridRowsChangeset', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: IndexRowOrder.create) ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) @@ -866,8 +866,8 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage { ..hasRequiredFields = false ; - GridBlockOrderChangeset._() : super(); - factory GridBlockOrderChangeset({ + GridRowsChangeset._() : super(); + factory GridRowsChangeset({ $core.String? blockId, $core.Iterable? insertedRows, $core.Iterable? deletedRows, @@ -888,26 +888,26 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage { } return _result; } - factory GridBlockOrderChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlockOrderChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridRowsChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridRowsChangeset.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') - GridBlockOrderChangeset clone() => GridBlockOrderChangeset()..mergeFromMessage(this); + GridRowsChangeset clone() => GridRowsChangeset()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GridBlockOrderChangeset copyWith(void Function(GridBlockOrderChangeset) updates) => super.copyWith((message) => updates(message as GridBlockOrderChangeset)) as GridBlockOrderChangeset; // ignore: deprecated_member_use + GridRowsChangeset copyWith(void Function(GridRowsChangeset) updates) => super.copyWith((message) => updates(message as GridRowsChangeset)) as GridRowsChangeset; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GridBlockOrderChangeset create() => GridBlockOrderChangeset._(); - GridBlockOrderChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridRowsChangeset create() => GridRowsChangeset._(); + GridRowsChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridBlockOrderChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlockOrderChangeset? _defaultInstance; + static GridRowsChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridRowsChangeset? _defaultInstance; @$pb.TagNumber(1) $core.String get blockId => $_getSZ(0); @@ -1950,6 +1950,109 @@ class FieldChangesetPayload extends $pb.GeneratedMessage { void clearTypeOptionData() => clearField(9); } +class MoveItemPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MoveItemPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'itemId') + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fromIndex', $pb.PbFieldType.O3) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'toIndex', $pb.PbFieldType.O3) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: MoveItemType.MoveField, valueOf: MoveItemType.valueOf, enumValues: MoveItemType.values) + ..hasRequiredFields = false + ; + + MoveItemPayload._() : super(); + factory MoveItemPayload({ + $core.String? gridId, + $core.String? itemId, + $core.int? fromIndex, + $core.int? toIndex, + MoveItemType? ty, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (itemId != null) { + _result.itemId = itemId; + } + if (fromIndex != null) { + _result.fromIndex = fromIndex; + } + if (toIndex != null) { + _result.toIndex = toIndex; + } + if (ty != null) { + _result.ty = ty; + } + return _result; + } + factory MoveItemPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MoveItemPayload.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') + MoveItemPayload clone() => MoveItemPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MoveItemPayload copyWith(void Function(MoveItemPayload) updates) => super.copyWith((message) => updates(message as MoveItemPayload)) as MoveItemPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MoveItemPayload create() => MoveItemPayload._(); + MoveItemPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MoveItemPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MoveItemPayload? _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 itemId => $_getSZ(1); + @$pb.TagNumber(2) + set itemId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasItemId() => $_has(1); + @$pb.TagNumber(2) + void clearItemId() => clearField(2); + + @$pb.TagNumber(3) + $core.int get fromIndex => $_getIZ(2); + @$pb.TagNumber(3) + set fromIndex($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasFromIndex() => $_has(2); + @$pb.TagNumber(3) + void clearFromIndex() => clearField(3); + + @$pb.TagNumber(4) + $core.int get toIndex => $_getIZ(3); + @$pb.TagNumber(4) + set toIndex($core.int v) { $_setSignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasToIndex() => $_has(3); + @$pb.TagNumber(4) + void clearToIndex() => clearField(4); + + @$pb.TagNumber(5) + MoveItemType get ty => $_getN(4); + @$pb.TagNumber(5) + set ty(MoveItemType v) { setField(5, v); } + @$pb.TagNumber(5) + $core.bool hasTy() => $_has(4); + @$pb.TagNumber(5) + void clearTy() => clearField(5); +} + enum CellChangeset_OneOfData { data, notSet diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart index 661b26532c..e6cb17314b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart @@ -9,6 +9,21 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +class MoveItemType extends $pb.ProtobufEnum { + static const MoveItemType MoveField = MoveItemType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveField'); + static const MoveItemType MoveRow = MoveItemType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveRow'); + + static const $core.List values = [ + MoveField, + MoveRow, + ]; + + static final $core.Map<$core.int, MoveItemType> _byValue = $pb.ProtobufEnum.initByValue(values); + static MoveItemType? valueOf($core.int value) => _byValue[value]; + + const MoveItemType._($core.int v, $core.String n) : super(v, n); +} + 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'); 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 0f8165fb8d..09cac1722c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -8,6 +8,17 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use moveItemTypeDescriptor instead') +const MoveItemType$json = const { + '1': 'MoveItemType', + '2': const [ + const {'1': 'MoveField', '2': 0}, + const {'1': 'MoveRow', '2': 1}, + ], +}; + +/// Descriptor for `MoveItemType`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List moveItemTypeDescriptor = $convert.base64Decode('CgxNb3ZlSXRlbVR5cGUSDQoJTW92ZUZpZWxkEAASCwoHTW92ZVJvdxAB'); @$core.Deprecated('Use fieldTypeDescriptor instead') const FieldType$json = const { '1': 'FieldType', @@ -186,9 +197,9 @@ const GridBlockOrder$json = const { /// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIoCgpyb3dfb3JkZXJzGAIgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); -@$core.Deprecated('Use gridBlockOrderChangesetDescriptor instead') -const GridBlockOrderChangeset$json = const { - '1': 'GridBlockOrderChangeset', +@$core.Deprecated('Use gridRowsChangesetDescriptor instead') +const GridRowsChangeset$json = const { + '1': 'GridRowsChangeset', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.IndexRowOrder', '10': 'insertedRows'}, @@ -197,8 +208,8 @@ const GridBlockOrderChangeset$json = const { ], }; -/// Descriptor for `GridBlockOrderChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockOrderChangesetDescriptor = $convert.base64Decode('ChdHcmlkQmxvY2tPcmRlckNoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M='); +/// Descriptor for `GridRowsChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridRowsChangesetDescriptor = $convert.base64Decode('ChFHcmlkUm93c0NoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M='); @$core.Deprecated('Use indexRowOrderDescriptor instead') const IndexRowOrder$json = const { '1': 'IndexRowOrder', @@ -370,6 +381,20 @@ const FieldChangesetPayload$json = const { /// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ=='); +@$core.Deprecated('Use moveItemPayloadDescriptor instead') +const MoveItemPayload$json = const { + '1': 'MoveItemPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'item_id', '3': 2, '4': 1, '5': 9, '10': 'itemId'}, + const {'1': 'from_index', '3': 3, '4': 1, '5': 5, '10': 'fromIndex'}, + const {'1': 'to_index', '3': 4, '4': 1, '5': 5, '10': 'toIndex'}, + const {'1': 'ty', '3': 5, '4': 1, '5': 14, '6': '.MoveItemType', '10': 'ty'}, + ], +}; + +/// Descriptor for `MoveItemPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List moveItemPayloadDescriptor = $convert.base64Decode('Cg9Nb3ZlSXRlbVBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhcKB2l0ZW1faWQYAiABKAlSBml0ZW1JZBIdCgpmcm9tX2luZGV4GAMgASgFUglmcm9tSW5kZXgSGQoIdG9faW5kZXgYBCABKAVSB3RvSW5kZXgSHQoCdHkYBSABKA4yDS5Nb3ZlSXRlbVR5cGVSAnR5'); @$core.Deprecated('Use cellChangesetDescriptor instead') const CellChangeset$json = const { '1': 'CellChangeset', 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 b4bde9790b..4c898182c7 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 @@ -19,6 +19,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent SwitchToField = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SwitchToField'); static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField'); static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext'); + static const GridEvent MoveItem = GridEvent._(17, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveItem'); static const GridEvent NewSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewSelectOption'); static const GridEvent GetSelectOptionContext = GridEvent._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetSelectOptionContext'); static const GridEvent UpdateSelectOption = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateSelectOption'); @@ -40,6 +41,7 @@ class GridEvent extends $pb.ProtobufEnum { SwitchToField, DuplicateField, GetEditFieldContext, + MoveItem, NewSelectOption, GetSelectOptionContext, UpdateSelectOption, 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 272b82e375..b03ea1cc64 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 @@ -21,6 +21,7 @@ const GridEvent$json = const { const {'1': 'SwitchToField', '2': 14}, const {'1': 'DuplicateField', '2': 15}, const {'1': 'GetEditFieldContext', '2': 16}, + const {'1': 'MoveItem', '2': 17}, const {'1': 'NewSelectOption', '2': 30}, const {'1': 'GetSelectOptionContext', '2': 31}, const {'1': 'UpdateSelectOption', '2': 32}, @@ -35,4 +36,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtJbnNlcnRGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIWChJVcGRhdGVTZWxlY3RPcHRpb24QIBINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxINCglEZWxldGVSb3cQNBIQCgxEdXBsaWNhdGVSb3cQNRILCgdHZXRDZWxsEEYSDgoKVXBkYXRlQ2VsbBBHEhoKFlVwZGF0ZUNlbGxTZWxlY3RPcHRpb24QSA=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtJbnNlcnRGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEgwKCE1vdmVJdGVtEBESEwoPTmV3U2VsZWN0T3B0aW9uEB4SGgoWR2V0U2VsZWN0T3B0aW9uQ29udGV4dBAfEhYKElVwZGF0ZVNlbGVjdE9wdGlvbhAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg0KCURlbGV0ZVJvdxA0EhAKDER1cGxpY2F0ZVJvdxA1EgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSGgoWVXBkYXRlQ2VsbFNlbGVjdE9wdGlvbhBI'); diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index 428982c60e..1a3a3172f4 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -947,6 +947,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1+1" + reorderables: + dependency: "direct main" + description: + name: reorderables + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.3" shared_preferences: dependency: transitive description: diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 495e2482cd..bcc3303602 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -74,6 +74,7 @@ dependencies: device_info_plus: ^3.2.1 fluttertoast: ^8.0.8 table_calendar: ^3.0.5 + reorderables: dev_dependencies: flutter_lints: ^1.0.0 diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e9f0bda61e..9efdf0d01f 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -130,6 +130,17 @@ pub(crate) async fn get_field_context_handler( data_result(edit_context) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn move_item_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let params: MoveItemParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let _ = editor.move_item(params).await?; + Ok(()) +} + async fn make_field_edit_context( grid_id: &str, field_id: Option, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 08a2a25313..67cbebe2d9 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -17,6 +17,8 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::DeleteField, delete_field_handler) .event(GridEvent::SwitchToField, switch_to_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) + .event(GridEvent::GetEditFieldContext, get_field_context_handler) + .event(GridEvent::MoveItem, move_item_handler) // Row .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) @@ -29,9 +31,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::NewSelectOption, new_select_option_handler) .event(GridEvent::UpdateSelectOption, update_select_option_handler) .event(GridEvent::GetSelectOptionContext, get_select_option_handler) - .event(GridEvent::UpdateCellSelectOption, update_cell_select_option_handler) - // - .event(GridEvent::GetEditFieldContext, get_field_context_handler); + .event(GridEvent::UpdateCellSelectOption, update_cell_select_option_handler); module } @@ -66,6 +66,9 @@ pub enum GridEvent { #[event(input = "GetEditFieldContextPayload", output = "EditFieldContext")] GetEditFieldContext = 16, + #[event(input = "MoveItemPayload")] + MoveItem = 17, + #[event(input = "SelectOptionName", output = "SelectOption")] NewSelectOption = 30, 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 c474939b47..b4792931ae 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 @@ -34,6 +34,7 @@ pub enum GridEvent { SwitchToField = 14, DuplicateField = 15, GetEditFieldContext = 16, + MoveItem = 17, NewSelectOption = 30, GetSelectOptionContext = 31, UpdateSelectOption = 32, @@ -62,6 +63,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 14 => ::std::option::Option::Some(GridEvent::SwitchToField), 15 => ::std::option::Option::Some(GridEvent::DuplicateField), 16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext), + 17 => ::std::option::Option::Some(GridEvent::MoveItem), 30 => ::std::option::Option::Some(GridEvent::NewSelectOption), 31 => ::std::option::Option::Some(GridEvent::GetSelectOptionContext), 32 => ::std::option::Option::Some(GridEvent::UpdateSelectOption), @@ -87,6 +89,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::SwitchToField, GridEvent::DuplicateField, GridEvent::GetEditFieldContext, + GridEvent::MoveItem, GridEvent::NewSelectOption, GridEvent::GetSelectOptionContext, GridEvent::UpdateSelectOption, @@ -125,16 +128,16 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xef\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xfd\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bInsertField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ - ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\ - lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x16\n\ - \x12UpdateSelectOption\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\x06GetRow\ - \x103\x12\r\n\tDeleteRow\x104\x12\x10\n\x0cDuplicateRow\x105\x12\x0b\n\ - \x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\x1a\n\x16UpdateCellSelec\ - tOption\x10Hb\x06proto3\ + ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x0c\n\x08MoveI\ + tem\x10\x11\x12\x13\n\x0fNewSelectOption\x10\x1e\x12\x1a\n\x16GetSelectO\ + ptionContext\x10\x1f\x12\x16\n\x12UpdateSelectOption\x10\x20\x12\r\n\tCr\ + eateRow\x102\x12\n\n\x06GetRow\x103\x12\r\n\tDeleteRow\x104\x12\x10\n\ + \x0cDuplicateRow\x105\x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\ + \x10G\x12\x1a\n\x16UpdateCellSelectOption\x10Hb\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 eb66389430..7f45db5761 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 @@ -10,6 +10,7 @@ enum GridEvent { SwitchToField = 14; DuplicateField = 15; GetEditFieldContext = 16; + MoveItem = 17; NewSelectOption = 30; GetSelectOptionContext = 31; UpdateSelectOption = 32; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index b1817c85a6..0eda4615bf 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -8,8 +8,8 @@ use std::borrow::Cow; use dashmap::DashMap; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - CellChangeset, CellMeta, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, - GridBlockOrderChangeset, IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder, + CellChangeset, CellMeta, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridRowsChangeset, + IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{RevisionManager, RevisionPersistence}; @@ -76,7 +76,7 @@ impl GridBlockMetaEditorManager { index_row_order.index = row_index; let _ = self - .notify_did_update_grid_rows(GridBlockOrderChangeset::from_insert(block_id, vec![index_row_order])) + .notify_did_update_grid_rows(GridRowsChangeset::insert(block_id, vec![index_row_order])) .await?; Ok(row_count) } @@ -98,7 +98,7 @@ impl GridBlockMetaEditorManager { changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); let _ = self - .notify_did_update_grid_rows(GridBlockOrderChangeset::from_insert(&block_id, inserted_row_orders)) + .notify_did_update_grid_rows(GridRowsChangeset::insert(&block_id, inserted_row_orders)) .await?; } @@ -116,7 +116,7 @@ impl GridBlockMetaEditorManager { { None => {} Some(row_order) => { - let block_order_changeset = GridBlockOrderChangeset::from_update(&editor.block_id, vec![row_order]); + let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); let _ = self.notify_did_update_grid_rows(block_order_changeset).await?; } } @@ -131,7 +131,7 @@ impl GridBlockMetaEditorManager { let row_orders = editor.get_row_orders(Some(vec![Cow::Borrowed(&row_id)])).await?; let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?; let _ = self - .notify_did_update_grid_rows(GridBlockOrderChangeset::from_delete(&block_id, row_orders)) + .notify_did_update_grid_rows(GridRowsChangeset::delete(&block_id, row_orders)) .await?; Ok(()) @@ -213,7 +213,7 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn notify_did_update_grid_rows(&self, changeset: GridBlockOrderChangeset) -> FlowyResult<()> { + async fn notify_did_update_grid_rows(&self, changeset: GridRowsChangeset) -> FlowyResult<()> { send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock) .payload(changeset) .send(); 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 f78adda837..f65179ebd3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -375,6 +375,24 @@ impl ClientGridEditor { Ok(snapshots) } + pub async fn move_item(&self, params: MoveItemParams) -> FlowyResult<()> { + match params.ty { + MoveItemType::MoveField => { + self.move_field(params.from_index, params.to_index, ¶ms.item_id) + .await + } + MoveItemType::MoveRow => self.move_row(params.from_index, params.to_index, ¶ms.item_id).await, + } + } + + pub async fn move_field(&self, from: i32, to: i32, field_id: &str) -> FlowyResult<()> { + todo!() + } + + pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> { + todo!() + } + pub async fn delta_bytes(&self) -> Bytes { self.pad.read().await.delta_bytes() } 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 eddbc4b19f..0becd3d665 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -278,7 +278,7 @@ impl GridBlockOrder { } #[derive(Debug, Clone, Default, ProtoBuf)] -pub struct GridBlockOrderChangeset { +pub struct GridRowsChangeset { #[pb(index = 1)] pub block_id: String, @@ -314,8 +314,8 @@ impl std::convert::From<&RowMeta> for IndexRowOrder { } } -impl GridBlockOrderChangeset { - pub fn from_insert(block_id: &str, inserted_rows: Vec) -> Self { +impl GridRowsChangeset { + pub fn insert(block_id: &str, inserted_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows, @@ -324,7 +324,7 @@ impl GridBlockOrderChangeset { } } - pub fn from_delete(block_id: &str, deleted_rows: Vec) -> Self { + pub fn delete(block_id: &str, deleted_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows: vec![], @@ -333,7 +333,7 @@ impl GridBlockOrderChangeset { } } - pub fn from_update(block_id: &str, updated_rows: Vec) -> Self { + pub fn update(block_id: &str, updated_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows: vec![], @@ -656,6 +656,61 @@ impl TryInto for FieldChangesetPayload { } } +#[derive(Debug, Clone, ProtoBuf_Enum)] +pub enum MoveItemType { + MoveField = 0, + MoveRow = 1, +} + +impl std::default::Default for MoveItemType { + fn default() -> Self { + MoveItemType::MoveField + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct MoveItemPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub item_id: String, + + #[pb(index = 3)] + pub from_index: i32, + + #[pb(index = 4)] + pub to_index: i32, + + #[pb(index = 5)] + pub ty: MoveItemType, +} + +#[derive(Clone)] +pub struct MoveItemParams { + pub grid_id: String, + pub item_id: String, + pub from_index: i32, + pub to_index: i32, + pub ty: MoveItemType, +} + +impl TryInto for MoveItemPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let item_id = NotEmptyStr::parse(self.item_id).map_err(|_| ErrorCode::InvalidData)?; + Ok(MoveItemParams { + grid_id: grid_id.0, + item_id: item_id.0, + from_index: self.from_index, + to_index: self.to_index, + ty: self.ty, + }) + } +} + #[derive( Debug, Clone, diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 6f2e7d1787..15e85282f8 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 @@ -2920,7 +2920,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { } #[derive(PartialEq,Clone,Default)] -pub struct GridBlockOrderChangeset { +pub struct GridRowsChangeset { // message fields pub block_id: ::std::string::String, pub inserted_rows: ::protobuf::RepeatedField, @@ -2931,14 +2931,14 @@ pub struct GridBlockOrderChangeset { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridBlockOrderChangeset { - fn default() -> &'a GridBlockOrderChangeset { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridRowsChangeset { + fn default() -> &'a GridRowsChangeset { + ::default_instance() } } -impl GridBlockOrderChangeset { - pub fn new() -> GridBlockOrderChangeset { +impl GridRowsChangeset { + pub fn new() -> GridRowsChangeset { ::std::default::Default::default() } @@ -3044,7 +3044,7 @@ impl GridBlockOrderChangeset { } } -impl ::protobuf::Message for GridBlockOrderChangeset { +impl ::protobuf::Message for GridRowsChangeset { fn is_initialized(&self) -> bool { for v in &self.inserted_rows { if !v.is_initialized() { @@ -3161,8 +3161,8 @@ impl ::protobuf::Message for GridBlockOrderChangeset { Self::descriptor_static() } - fn new() -> GridBlockOrderChangeset { - GridBlockOrderChangeset::new() + fn new() -> GridRowsChangeset { + GridRowsChangeset::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -3171,39 +3171,39 @@ impl ::protobuf::Message for GridBlockOrderChangeset { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &GridBlockOrderChangeset| { &m.block_id }, - |m: &mut GridBlockOrderChangeset| { &mut m.block_id }, + |m: &GridRowsChangeset| { &m.block_id }, + |m: &mut GridRowsChangeset| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "inserted_rows", - |m: &GridBlockOrderChangeset| { &m.inserted_rows }, - |m: &mut GridBlockOrderChangeset| { &mut m.inserted_rows }, + |m: &GridRowsChangeset| { &m.inserted_rows }, + |m: &mut GridRowsChangeset| { &mut m.inserted_rows }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "deleted_rows", - |m: &GridBlockOrderChangeset| { &m.deleted_rows }, - |m: &mut GridBlockOrderChangeset| { &mut m.deleted_rows }, + |m: &GridRowsChangeset| { &m.deleted_rows }, + |m: &mut GridRowsChangeset| { &mut m.deleted_rows }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "updated_rows", - |m: &GridBlockOrderChangeset| { &m.updated_rows }, - |m: &mut GridBlockOrderChangeset| { &mut m.updated_rows }, + |m: &GridRowsChangeset| { &m.updated_rows }, + |m: &mut GridRowsChangeset| { &mut m.updated_rows }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlockOrderChangeset", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridRowsChangeset", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridBlockOrderChangeset { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlockOrderChangeset::new) + fn default_instance() -> &'static GridRowsChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridRowsChangeset::new) } } -impl ::protobuf::Clear for GridBlockOrderChangeset { +impl ::protobuf::Clear for GridRowsChangeset { fn clear(&mut self) { self.block_id.clear(); self.inserted_rows.clear(); @@ -3213,13 +3213,13 @@ impl ::protobuf::Clear for GridBlockOrderChangeset { } } -impl ::std::fmt::Debug for GridBlockOrderChangeset { +impl ::std::fmt::Debug for GridRowsChangeset { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridBlockOrderChangeset { +impl ::protobuf::reflect::ProtobufValue for GridRowsChangeset { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -6512,6 +6512,308 @@ impl ::protobuf::reflect::ProtobufValue for FieldChangesetPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct MoveItemPayload { + // message fields + pub grid_id: ::std::string::String, + pub item_id: ::std::string::String, + pub from_index: i32, + pub to_index: i32, + pub ty: MoveItemType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MoveItemPayload { + fn default() -> &'a MoveItemPayload { + ::default_instance() + } +} + +impl MoveItemPayload { + pub fn new() -> MoveItemPayload { + ::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 item_id = 2; + + + pub fn get_item_id(&self) -> &str { + &self.item_id + } + pub fn clear_item_id(&mut self) { + self.item_id.clear(); + } + + // Param is passed by value, moved + pub fn set_item_id(&mut self, v: ::std::string::String) { + self.item_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_item_id(&mut self) -> &mut ::std::string::String { + &mut self.item_id + } + + // Take field + pub fn take_item_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.item_id, ::std::string::String::new()) + } + + // int32 from_index = 3; + + + pub fn get_from_index(&self) -> i32 { + self.from_index + } + pub fn clear_from_index(&mut self) { + self.from_index = 0; + } + + // Param is passed by value, moved + pub fn set_from_index(&mut self, v: i32) { + self.from_index = v; + } + + // int32 to_index = 4; + + + pub fn get_to_index(&self) -> i32 { + self.to_index + } + pub fn clear_to_index(&mut self) { + self.to_index = 0; + } + + // Param is passed by value, moved + pub fn set_to_index(&mut self, v: i32) { + self.to_index = v; + } + + // .MoveItemType ty = 5; + + + pub fn get_ty(&self) -> MoveItemType { + self.ty + } + pub fn clear_ty(&mut self) { + self.ty = MoveItemType::MoveField; + } + + // Param is passed by value, moved + pub fn set_ty(&mut self, v: MoveItemType) { + self.ty = v; + } +} + +impl ::protobuf::Message for MoveItemPayload { + 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.item_id)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.from_index = tmp; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.to_index = tmp; + }, + 5 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.ty, 5, &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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.item_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.item_id); + } + if self.from_index != 0 { + my_size += ::protobuf::rt::value_size(3, self.from_index, ::protobuf::wire_format::WireTypeVarint); + } + if self.to_index != 0 { + my_size += ::protobuf::rt::value_size(4, self.to_index, ::protobuf::wire_format::WireTypeVarint); + } + if self.ty != MoveItemType::MoveField { + my_size += ::protobuf::rt::enum_size(5, self.ty); + } + 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.item_id.is_empty() { + os.write_string(2, &self.item_id)?; + } + if self.from_index != 0 { + os.write_int32(3, self.from_index)?; + } + if self.to_index != 0 { + os.write_int32(4, self.to_index)?; + } + if self.ty != MoveItemType::MoveField { + os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.ty))?; + } + 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() -> MoveItemPayload { + MoveItemPayload::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: &MoveItemPayload| { &m.grid_id }, + |m: &mut MoveItemPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "item_id", + |m: &MoveItemPayload| { &m.item_id }, + |m: &mut MoveItemPayload| { &mut m.item_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "from_index", + |m: &MoveItemPayload| { &m.from_index }, + |m: &mut MoveItemPayload| { &mut m.from_index }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "to_index", + |m: &MoveItemPayload| { &m.to_index }, + |m: &mut MoveItemPayload| { &mut m.to_index }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "ty", + |m: &MoveItemPayload| { &m.ty }, + |m: &mut MoveItemPayload| { &mut m.ty }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MoveItemPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MoveItemPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MoveItemPayload::new) + } +} + +impl ::protobuf::Clear for MoveItemPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.item_id.clear(); + self.from_index = 0; + self.to_index = 0; + self.ty = MoveItemType::MoveField; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MoveItemPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MoveItemPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CellChangeset { // message fields @@ -6837,6 +7139,56 @@ impl ::protobuf::reflect::ProtobufValue for CellChangeset { } } +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum MoveItemType { + MoveField = 0, + MoveRow = 1, +} + +impl ::protobuf::ProtobufEnum for MoveItemType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(MoveItemType::MoveField), + 1 => ::std::option::Option::Some(MoveItemType::MoveRow), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [MoveItemType] = &[ + MoveItemType::MoveField, + MoveItemType::MoveRow, + ]; + 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::("MoveItemType", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for MoveItemType { +} + +impl ::std::default::Default for MoveItemType { + fn default() -> Self { + MoveItemType::MoveField + } +} + +impl ::protobuf::reflect::ProtobufValue for MoveItemType { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -6932,19 +7284,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ \x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\x12\x19\n\ \x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\x18\x02\ - \x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc5\x01\n\x17GridBlockOrderChang\ - eset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\rinsert\ - ed_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\x12,\n\ - \x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\ - \x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"_\n\r\ - IndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08row\ - Order\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone\ - _of_index\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\ - \n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\ - \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07conte\ - nt\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_i\ - d\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ + \x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xbf\x01\n\x11GridRowsChangeset\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\rinserted_r\ + ows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\x12,\n\x0cd\ + eleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\x0cu\ + pdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"_\n\rIndex\ + RowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrder\ + \x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_i\ + ndex\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nr\ + ow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ + \x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\x12\ + \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\ + \x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ \x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\ \x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\ \x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04nam\ @@ -6971,14 +7323,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\ \x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one\ _of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\ - \x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x7f\n\rCellChangese\ - t\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ - \x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\ - \x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone\ - _of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ - \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ - \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ - o3\ + \x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0fMoveIt\ + emPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x17\n\ + \x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\x18\x03\ + \x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\x05R\ + \x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\x02ty\ + \"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ + Id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_i\ + d\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0\ + R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\tMoveField\x10\ + \0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\ + \0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0c\ + SingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Check\ + box\x10\x05b\x06proto3\ "; 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 e5950858f0..eca5a5f0ea 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 @@ -58,7 +58,7 @@ message GridBlockOrder { string block_id = 1; repeated RowOrder row_orders = 2; } -message GridBlockOrderChangeset { +message GridRowsChangeset { string block_id = 1; repeated IndexRowOrder inserted_rows = 2; repeated RowOrder deleted_rows = 3; @@ -123,12 +123,23 @@ message FieldChangesetPayload { oneof one_of_width { int32 width = 8; }; oneof one_of_type_option_data { bytes type_option_data = 9; }; } +message MoveItemPayload { + string grid_id = 1; + string item_id = 2; + int32 from_index = 3; + int32 to_index = 4; + MoveItemType ty = 5; +} message CellChangeset { string grid_id = 1; string row_id = 2; string field_id = 3; oneof one_of_data { string data = 4; }; } +enum MoveItemType { + MoveField = 0; + MoveRow = 1; +} enum FieldType { RichText = 0; Number = 1; From 06af45a8ed8f92633de0a0d81a82a157b60526f2 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 13 Apr 2022 21:26:27 +0800 Subject: [PATCH 150/179] chore: udpate field notification --- .../flowy-grid-data-model/grid.pb.dart | 289 +++- .../flowy-grid-data-model/grid.pbjson.dart | 53 +- .../src/services/block_meta_manager.rs | 10 +- .../flowy-grid/src/services/grid_editor.rs | 21 +- .../src/entities/grid.rs | 71 +- .../src/protobuf/model/grid.rs | 1158 ++++++++++++----- .../src/protobuf/proto/grid.proto | 18 +- .../src/client_grid/grid_meta_pad.rs | 30 +- 8 files changed, 1227 insertions(+), 423 deletions(-) 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 1452679e63..1212cb506e 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 @@ -254,6 +254,153 @@ class FieldOrder extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); } +class GridFieldChangeset extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridFieldChangeset', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedFields', $pb.PbFieldType.PM, subBuilder: IndexField.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedFields', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) + ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedFields', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + GridFieldChangeset._() : super(); + factory GridFieldChangeset({ + $core.String? gridId, + $core.Iterable? insertedFields, + $core.Iterable? deletedFields, + $core.Iterable? updatedFields, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (insertedFields != null) { + _result.insertedFields.addAll(insertedFields); + } + if (deletedFields != null) { + _result.deletedFields.addAll(deletedFields); + } + if (updatedFields != null) { + _result.updatedFields.addAll(updatedFields); + } + return _result; + } + factory GridFieldChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridFieldChangeset.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') + GridFieldChangeset clone() => GridFieldChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridFieldChangeset copyWith(void Function(GridFieldChangeset) updates) => super.copyWith((message) => updates(message as GridFieldChangeset)) as GridFieldChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridFieldChangeset create() => GridFieldChangeset._(); + GridFieldChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridFieldChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridFieldChangeset? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get insertedFields => $_getList(1); + + @$pb.TagNumber(3) + $core.List get deletedFields => $_getList(2); + + @$pb.TagNumber(4) + $core.List get updatedFields => $_getList(3); +} + +enum IndexField_OneOfIndex { + index_, + notSet +} + +class IndexField extends $pb.GeneratedMessage { + static const $core.Map<$core.int, IndexField_OneOfIndex> _IndexField_OneOfIndexByTag = { + 2 : IndexField_OneOfIndex.index_, + 0 : IndexField_OneOfIndex.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'IndexField', createEmptyInstance: create) + ..oo(0, [2]) + ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'index', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + IndexField._() : super(); + factory IndexField({ + Field? field_1, + $core.int? index, + }) { + final _result = create(); + if (field_1 != null) { + _result.field_1 = field_1; + } + if (index != null) { + _result.index = index; + } + return _result; + } + factory IndexField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory IndexField.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') + IndexField clone() => IndexField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + IndexField copyWith(void Function(IndexField) updates) => super.copyWith((message) => updates(message as IndexField)) as IndexField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static IndexField create() => IndexField._(); + IndexField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static IndexField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static IndexField? _defaultInstance; + + IndexField_OneOfIndex whichOneOfIndex() => _IndexField_OneOfIndexByTag[$_whichOneof(0)]!; + void clearOneOfIndex() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + Field get field_1 => $_getN(0); + @$pb.TagNumber(1) + set field_1(Field v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasField_1() => $_has(0); + @$pb.TagNumber(1) + void clearField_1() => clearField(1); + @$pb.TagNumber(1) + Field ensureField_1() => $_ensure(0); + + @$pb.TagNumber(2) + $core.int get index => $_getIZ(1); + @$pb.TagNumber(2) + set index($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasIndex() => $_has(1); + @$pb.TagNumber(2) + void clearIndex() => clearField(2); +} + enum GetEditFieldContextPayload_OneOfFieldId { fieldId, notSet @@ -857,77 +1004,6 @@ class GridBlockOrder extends $pb.GeneratedMessage { $core.List get rowOrders => $_getList(1); } -class GridRowsChangeset extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridRowsChangeset', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: IndexRowOrder.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) - ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) - ..hasRequiredFields = false - ; - - GridRowsChangeset._() : super(); - factory GridRowsChangeset({ - $core.String? blockId, - $core.Iterable? insertedRows, - $core.Iterable? deletedRows, - $core.Iterable? updatedRows, - }) { - final _result = create(); - if (blockId != null) { - _result.blockId = blockId; - } - if (insertedRows != null) { - _result.insertedRows.addAll(insertedRows); - } - if (deletedRows != null) { - _result.deletedRows.addAll(deletedRows); - } - if (updatedRows != null) { - _result.updatedRows.addAll(updatedRows); - } - return _result; - } - factory GridRowsChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridRowsChangeset.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') - GridRowsChangeset clone() => GridRowsChangeset()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridRowsChangeset copyWith(void Function(GridRowsChangeset) updates) => super.copyWith((message) => updates(message as GridRowsChangeset)) as GridRowsChangeset; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridRowsChangeset create() => GridRowsChangeset._(); - GridRowsChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridRowsChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridRowsChangeset? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get blockId => $_getSZ(0); - @$pb.TagNumber(1) - set blockId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBlockId() => $_has(0); - @$pb.TagNumber(1) - void clearBlockId() => clearField(1); - - @$pb.TagNumber(2) - $core.List get insertedRows => $_getList(1); - - @$pb.TagNumber(3) - $core.List get deletedRows => $_getList(2); - - @$pb.TagNumber(4) - $core.List get updatedRows => $_getList(3); -} - enum IndexRowOrder_OneOfIndex { index_, notSet @@ -1004,6 +1080,77 @@ class IndexRowOrder extends $pb.GeneratedMessage { void clearIndex() => clearField(2); } +class GridRowsChangeset extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridRowsChangeset', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: IndexRowOrder.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..hasRequiredFields = false + ; + + GridRowsChangeset._() : super(); + factory GridRowsChangeset({ + $core.String? blockId, + $core.Iterable? insertedRows, + $core.Iterable? deletedRows, + $core.Iterable? updatedRows, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (insertedRows != null) { + _result.insertedRows.addAll(insertedRows); + } + if (deletedRows != null) { + _result.deletedRows.addAll(deletedRows); + } + if (updatedRows != null) { + _result.updatedRows.addAll(updatedRows); + } + return _result; + } + factory GridRowsChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridRowsChangeset.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') + GridRowsChangeset clone() => GridRowsChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridRowsChangeset copyWith(void Function(GridRowsChangeset) updates) => super.copyWith((message) => updates(message as GridRowsChangeset)) as GridRowsChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridRowsChangeset create() => GridRowsChangeset._(); + GridRowsChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridRowsChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridRowsChangeset? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get insertedRows => $_getList(1); + + @$pb.TagNumber(3) + $core.List get deletedRows => $_getList(2); + + @$pb.TagNumber(4) + $core.List get updatedRows => $_getList(3); +} + class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') 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 09cac1722c..a5d8fab78f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -72,6 +72,33 @@ const FieldOrder$json = const { /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); +@$core.Deprecated('Use gridFieldChangesetDescriptor instead') +const GridFieldChangeset$json = const { + '1': 'GridFieldChangeset', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'inserted_fields', '3': 2, '4': 3, '5': 11, '6': '.IndexField', '10': 'insertedFields'}, + const {'1': 'deleted_fields', '3': 3, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'deletedFields'}, + const {'1': 'updated_fields', '3': 4, '4': 3, '5': 11, '6': '.Field', '10': 'updatedFields'}, + ], +}; + +/// Descriptor for `GridFieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridFieldChangesetDescriptor = $convert.base64Decode('ChJHcmlkRmllbGRDaGFuZ2VzZXQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjQKD2luc2VydGVkX2ZpZWxkcxgCIAMoCzILLkluZGV4RmllbGRSDmluc2VydGVkRmllbGRzEjIKDmRlbGV0ZWRfZmllbGRzGAMgAygLMgsuRmllbGRPcmRlclINZGVsZXRlZEZpZWxkcxItCg51cGRhdGVkX2ZpZWxkcxgEIAMoCzIGLkZpZWxkUg11cGRhdGVkRmllbGRz'); +@$core.Deprecated('Use indexFieldDescriptor instead') +const IndexField$json = const { + '1': 'IndexField', + '2': const [ + const {'1': 'field', '3': 1, '4': 1, '5': 11, '6': '.Field', '10': 'field'}, + const {'1': 'index', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'index'}, + ], + '8': const [ + const {'1': 'one_of_index'}, + ], +}; + +/// Descriptor for `IndexField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List indexFieldDescriptor = $convert.base64Decode('CgpJbmRleEZpZWxkEhwKBWZpZWxkGAEgASgLMgYuRmllbGRSBWZpZWxkEhYKBWluZGV4GAIgASgFSABSBWluZGV4Qg4KDG9uZV9vZl9pbmRleA=='); @$core.Deprecated('Use getEditFieldContextPayloadDescriptor instead') const GetEditFieldContextPayload$json = const { '1': 'GetEditFieldContextPayload', @@ -197,19 +224,6 @@ const GridBlockOrder$json = const { /// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIoCgpyb3dfb3JkZXJzGAIgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); -@$core.Deprecated('Use gridRowsChangesetDescriptor instead') -const GridRowsChangeset$json = const { - '1': 'GridRowsChangeset', - '2': const [ - const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.IndexRowOrder', '10': 'insertedRows'}, - const {'1': 'deleted_rows', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'deletedRows'}, - const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.RowOrder', '10': 'updatedRows'}, - ], -}; - -/// Descriptor for `GridRowsChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridRowsChangesetDescriptor = $convert.base64Decode('ChFHcmlkUm93c0NoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M='); @$core.Deprecated('Use indexRowOrderDescriptor instead') const IndexRowOrder$json = const { '1': 'IndexRowOrder', @@ -224,6 +238,19 @@ const IndexRowOrder$json = const { /// Descriptor for `IndexRowOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List indexRowOrderDescriptor = $convert.base64Decode('Cg1JbmRleFJvd09yZGVyEiYKCXJvd19vcmRlchgBIAEoCzIJLlJvd09yZGVyUghyb3dPcmRlchIWCgVpbmRleBgCIAEoBUgAUgVpbmRleEIOCgxvbmVfb2ZfaW5kZXg='); +@$core.Deprecated('Use gridRowsChangesetDescriptor instead') +const GridRowsChangeset$json = const { + '1': 'GridRowsChangeset', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.IndexRowOrder', '10': 'insertedRows'}, + const {'1': 'deleted_rows', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'deletedRows'}, + const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.RowOrder', '10': 'updatedRows'}, + ], +}; + +/// Descriptor for `GridRowsChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridRowsChangesetDescriptor = $convert.base64Decode('ChFHcmlkUm93c0NoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 0eda4615bf..b5a35b10cd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -76,7 +76,7 @@ impl GridBlockMetaEditorManager { index_row_order.index = row_index; let _ = self - .notify_did_update_grid_rows(GridRowsChangeset::insert(block_id, vec![index_row_order])) + .notify_did_update_rows(GridRowsChangeset::insert(block_id, vec![index_row_order])) .await?; Ok(row_count) } @@ -98,7 +98,7 @@ impl GridBlockMetaEditorManager { changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); let _ = self - .notify_did_update_grid_rows(GridRowsChangeset::insert(&block_id, inserted_row_orders)) + .notify_did_update_rows(GridRowsChangeset::insert(&block_id, inserted_row_orders)) .await?; } @@ -117,7 +117,7 @@ impl GridBlockMetaEditorManager { None => {} Some(row_order) => { let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); - let _ = self.notify_did_update_grid_rows(block_order_changeset).await?; + let _ = self.notify_did_update_rows(block_order_changeset).await?; } } @@ -131,7 +131,7 @@ impl GridBlockMetaEditorManager { let row_orders = editor.get_row_orders(Some(vec![Cow::Borrowed(&row_id)])).await?; let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?; let _ = self - .notify_did_update_grid_rows(GridRowsChangeset::delete(&block_id, row_orders)) + .notify_did_update_rows(GridRowsChangeset::delete(&block_id, row_orders)) .await?; Ok(()) @@ -213,7 +213,7 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn notify_did_update_grid_rows(&self, changeset: GridRowsChangeset) -> FlowyResult<()> { + async fn notify_did_update_rows(&self, changeset: GridRowsChangeset) -> FlowyResult<()> { send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock) .payload(changeset) .send(); 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 f65179ebd3..8425097f69 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -151,7 +151,15 @@ impl ClientGridEditor { } pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.duplicate_field(field_id)?)).await?; + let mut duplicated_field_meta = None; + let _ = self + .modify(|grid| { + let (changeset, field_meta) = grid.duplicate_field(field_id)?; + duplicated_field_meta = field_meta; + Ok(changeset) + }) + .await?; + let _ = self.notify_did_update_grid().await?; Ok(()) } @@ -386,10 +394,12 @@ impl ClientGridEditor { } pub async fn move_field(&self, from: i32, to: i32, field_id: &str) -> FlowyResult<()> { + // GridFieldChangeset todo!() } pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> { + // GridRowsChangeset todo!() } @@ -436,6 +446,8 @@ impl ClientGridEditor { } async fn notify_did_update_grid(&self) -> FlowyResult<()> { + // GridFieldChangeset + let field_metas = self.get_field_metas::(None).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) @@ -444,6 +456,13 @@ impl ClientGridEditor { Ok(()) } + async fn notify_did_update_grid2(&self, changeset: GridFieldChangeset) -> FlowyResult<()> { + send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) + .payload(changeset) + .send(); + Ok(()) + } + #[tracing::instrument(level = "trace", skip_all, err)] async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; 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 0becd3d665..f090cfdc5e 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -84,6 +84,59 @@ impl std::convert::From for FieldOrder { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct GridFieldChangeset { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub inserted_fields: Vec, + + #[pb(index = 3)] + pub deleted_fields: Vec, + + #[pb(index = 4)] + pub updated_fields: Vec, +} + +impl GridFieldChangeset { + pub fn insert(grid_id: &str, inserted_fields: Vec) -> Self { + Self { + grid_id: grid_id.to_owned(), + inserted_fields, + deleted_fields: vec![], + updated_fields: vec![], + } + } + + pub fn delete(grid_id: &str, deleted_fields: Vec) -> Self { + Self { + grid_id: grid_id.to_string(), + inserted_fields: vec![], + deleted_fields, + updated_fields: vec![], + } + } + + pub fn update(grid_id: &str, updated_fields: Vec) -> Self { + Self { + grid_id: grid_id.to_string(), + inserted_fields: vec![], + deleted_fields: vec![], + updated_fields, + } + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct IndexField { + #[pb(index = 1)] + pub field: Field, + + #[pb(index = 2, one_of)] + pub index: Option, +} + #[derive(Debug, Default, ProtoBuf)] pub struct GetEditFieldContextPayload { #[pb(index = 1)] @@ -277,6 +330,15 @@ impl GridBlockOrder { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct IndexRowOrder { + #[pb(index = 1)] + pub row_order: RowOrder, + + #[pb(index = 2, one_of)] + pub index: Option, +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct GridRowsChangeset { #[pb(index = 1)] @@ -292,15 +354,6 @@ pub struct GridRowsChangeset { pub updated_rows: Vec, } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct IndexRowOrder { - #[pb(index = 1)] - pub row_order: RowOrder, - - #[pb(index = 2, one_of)] - pub index: Option, -} - impl std::convert::From for IndexRowOrder { fn from(row_order: RowOrder) -> Self { Self { row_order, index: None } 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 15e85282f8..46de6cf971 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 @@ -818,6 +818,544 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridFieldChangeset { + // message fields + pub grid_id: ::std::string::String, + pub inserted_fields: ::protobuf::RepeatedField, + pub deleted_fields: ::protobuf::RepeatedField, + pub updated_fields: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridFieldChangeset { + fn default() -> &'a GridFieldChangeset { + ::default_instance() + } +} + +impl GridFieldChangeset { + pub fn new() -> GridFieldChangeset { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // repeated .IndexField inserted_fields = 2; + + + pub fn get_inserted_fields(&self) -> &[IndexField] { + &self.inserted_fields + } + pub fn clear_inserted_fields(&mut self) { + self.inserted_fields.clear(); + } + + // Param is passed by value, moved + pub fn set_inserted_fields(&mut self, v: ::protobuf::RepeatedField) { + self.inserted_fields = v; + } + + // Mutable pointer to the field. + pub fn mut_inserted_fields(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.inserted_fields + } + + // Take field + pub fn take_inserted_fields(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.inserted_fields, ::protobuf::RepeatedField::new()) + } + + // repeated .FieldOrder deleted_fields = 3; + + + pub fn get_deleted_fields(&self) -> &[FieldOrder] { + &self.deleted_fields + } + pub fn clear_deleted_fields(&mut self) { + self.deleted_fields.clear(); + } + + // Param is passed by value, moved + pub fn set_deleted_fields(&mut self, v: ::protobuf::RepeatedField) { + self.deleted_fields = v; + } + + // Mutable pointer to the field. + pub fn mut_deleted_fields(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.deleted_fields + } + + // Take field + pub fn take_deleted_fields(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.deleted_fields, ::protobuf::RepeatedField::new()) + } + + // repeated .Field updated_fields = 4; + + + pub fn get_updated_fields(&self) -> &[Field] { + &self.updated_fields + } + pub fn clear_updated_fields(&mut self) { + self.updated_fields.clear(); + } + + // Param is passed by value, moved + pub fn set_updated_fields(&mut self, v: ::protobuf::RepeatedField) { + self.updated_fields = v; + } + + // Mutable pointer to the field. + pub fn mut_updated_fields(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.updated_fields + } + + // Take field + pub fn take_updated_fields(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.updated_fields, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridFieldChangeset { + fn is_initialized(&self) -> bool { + for v in &self.inserted_fields { + if !v.is_initialized() { + return false; + } + }; + for v in &self.deleted_fields { + if !v.is_initialized() { + return false; + } + }; + for v in &self.updated_fields { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.inserted_fields)?; + }, + 3 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.deleted_fields)?; + }, + 4 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.updated_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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + for value in &self.inserted_fields { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.deleted_fields { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.updated_fields { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + for v in &self.inserted_fields { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.deleted_fields { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.updated_fields { + 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() -> GridFieldChangeset { + GridFieldChangeset::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: &GridFieldChangeset| { &m.grid_id }, + |m: &mut GridFieldChangeset| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "inserted_fields", + |m: &GridFieldChangeset| { &m.inserted_fields }, + |m: &mut GridFieldChangeset| { &mut m.inserted_fields }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "deleted_fields", + |m: &GridFieldChangeset| { &m.deleted_fields }, + |m: &mut GridFieldChangeset| { &mut m.deleted_fields }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "updated_fields", + |m: &GridFieldChangeset| { &m.updated_fields }, + |m: &mut GridFieldChangeset| { &mut m.updated_fields }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridFieldChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridFieldChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridFieldChangeset::new) + } +} + +impl ::protobuf::Clear for GridFieldChangeset { + fn clear(&mut self) { + self.grid_id.clear(); + self.inserted_fields.clear(); + self.deleted_fields.clear(); + self.updated_fields.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridFieldChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridFieldChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct IndexField { + // message fields + pub field: ::protobuf::SingularPtrField, + // message oneof groups + pub one_of_index: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a IndexField { + fn default() -> &'a IndexField { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum IndexField_oneof_one_of_index { + index(i32), +} + +impl IndexField { + pub fn new() -> IndexField { + ::std::default::Default::default() + } + + // .Field field = 1; + + + pub fn get_field(&self) -> &Field { + self.field.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_field(&mut self) { + self.field.clear(); + } + + pub fn has_field(&self) -> bool { + self.field.is_some() + } + + // Param is passed by value, moved + pub fn set_field(&mut self, v: Field) { + self.field = ::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(&mut self) -> &mut Field { + if self.field.is_none() { + self.field.set_default(); + } + self.field.as_mut().unwrap() + } + + // Take field + pub fn take_field(&mut self) -> Field { + self.field.take().unwrap_or_else(|| Field::new()) + } + + // int32 index = 2; + + + pub fn get_index(&self) -> i32 { + match self.one_of_index { + ::std::option::Option::Some(IndexField_oneof_one_of_index::index(v)) => v, + _ => 0, + } + } + pub fn clear_index(&mut self) { + self.one_of_index = ::std::option::Option::None; + } + + pub fn has_index(&self) -> bool { + match self.one_of_index { + ::std::option::Option::Some(IndexField_oneof_one_of_index::index(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_index(&mut self, v: i32) { + self.one_of_index = ::std::option::Option::Some(IndexField_oneof_one_of_index::index(v)) + } +} + +impl ::protobuf::Message for IndexField { + fn is_initialized(&self) -> bool { + for v in &self.field { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_index = ::std::option::Option::Some(IndexField_oneof_one_of_index::index(is.read_int32()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.field.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let ::std::option::Option::Some(ref v) = self.one_of_index { + match v { + &IndexField_oneof_one_of_index::index(v) => { + my_size += ::protobuf::rt::value_size(2, v, ::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 let Some(ref v) = self.field.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_index { + match v { + &IndexField_oneof_one_of_index::index(v) => { + os.write_int32(2, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> IndexField { + IndexField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field", + |m: &IndexField| { &m.field }, + |m: &mut IndexField| { &mut m.field }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "index", + IndexField::has_index, + IndexField::get_index, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "IndexField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static IndexField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(IndexField::new) + } +} + +impl ::protobuf::Clear for IndexField { + fn clear(&mut self) { + self.field.clear(); + self.one_of_index = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for IndexField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for IndexField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GetEditFieldContextPayload { // message fields @@ -2919,6 +3457,238 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct IndexRowOrder { + // message fields + pub row_order: ::protobuf::SingularPtrField, + // message oneof groups + pub one_of_index: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a IndexRowOrder { + fn default() -> &'a IndexRowOrder { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum IndexRowOrder_oneof_one_of_index { + index(i32), +} + +impl IndexRowOrder { + pub fn new() -> IndexRowOrder { + ::std::default::Default::default() + } + + // .RowOrder row_order = 1; + + + pub fn get_row_order(&self) -> &RowOrder { + self.row_order.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_row_order(&mut self) { + self.row_order.clear(); + } + + pub fn has_row_order(&self) -> bool { + self.row_order.is_some() + } + + // Param is passed by value, moved + pub fn set_row_order(&mut self, v: RowOrder) { + self.row_order = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_order(&mut self) -> &mut RowOrder { + if self.row_order.is_none() { + self.row_order.set_default(); + } + self.row_order.as_mut().unwrap() + } + + // Take field + pub fn take_row_order(&mut self) -> RowOrder { + self.row_order.take().unwrap_or_else(|| RowOrder::new()) + } + + // int32 index = 2; + + + pub fn get_index(&self) -> i32 { + match self.one_of_index { + ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) => v, + _ => 0, + } + } + pub fn clear_index(&mut self) { + self.one_of_index = ::std::option::Option::None; + } + + pub fn has_index(&self) -> bool { + match self.one_of_index { + ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_index(&mut self, v: i32) { + self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) + } +} + +impl ::protobuf::Message for IndexRowOrder { + fn is_initialized(&self) -> bool { + for v in &self.row_order { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_order)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(is.read_int32()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.row_order.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let ::std::option::Option::Some(ref v) = self.one_of_index { + match v { + &IndexRowOrder_oneof_one_of_index::index(v) => { + my_size += ::protobuf::rt::value_size(2, v, ::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 let Some(ref v) = self.row_order.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_index { + match v { + &IndexRowOrder_oneof_one_of_index::index(v) => { + os.write_int32(2, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> IndexRowOrder { + IndexRowOrder::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_order", + |m: &IndexRowOrder| { &m.row_order }, + |m: &mut IndexRowOrder| { &mut m.row_order }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "index", + IndexRowOrder::has_index, + IndexRowOrder::get_index, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "IndexRowOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static IndexRowOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(IndexRowOrder::new) + } +} + +impl ::protobuf::Clear for IndexRowOrder { + fn clear(&mut self) { + self.row_order.clear(); + self.one_of_index = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for IndexRowOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for IndexRowOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GridRowsChangeset { // message fields @@ -3225,238 +3995,6 @@ impl ::protobuf::reflect::ProtobufValue for GridRowsChangeset { } } -#[derive(PartialEq,Clone,Default)] -pub struct IndexRowOrder { - // message fields - pub row_order: ::protobuf::SingularPtrField, - // message oneof groups - pub one_of_index: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a IndexRowOrder { - fn default() -> &'a IndexRowOrder { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum IndexRowOrder_oneof_one_of_index { - index(i32), -} - -impl IndexRowOrder { - pub fn new() -> IndexRowOrder { - ::std::default::Default::default() - } - - // .RowOrder row_order = 1; - - - pub fn get_row_order(&self) -> &RowOrder { - self.row_order.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_row_order(&mut self) { - self.row_order.clear(); - } - - pub fn has_row_order(&self) -> bool { - self.row_order.is_some() - } - - // Param is passed by value, moved - pub fn set_row_order(&mut self, v: RowOrder) { - self.row_order = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_order(&mut self) -> &mut RowOrder { - if self.row_order.is_none() { - self.row_order.set_default(); - } - self.row_order.as_mut().unwrap() - } - - // Take field - pub fn take_row_order(&mut self) -> RowOrder { - self.row_order.take().unwrap_or_else(|| RowOrder::new()) - } - - // int32 index = 2; - - - pub fn get_index(&self) -> i32 { - match self.one_of_index { - ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) => v, - _ => 0, - } - } - pub fn clear_index(&mut self) { - self.one_of_index = ::std::option::Option::None; - } - - pub fn has_index(&self) -> bool { - match self.one_of_index { - ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_index(&mut self, v: i32) { - self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) - } -} - -impl ::protobuf::Message for IndexRowOrder { - fn is_initialized(&self) -> bool { - for v in &self.row_order { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_order)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(is.read_int32()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let Some(ref v) = self.row_order.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if let ::std::option::Option::Some(ref v) = self.one_of_index { - match v { - &IndexRowOrder_oneof_one_of_index::index(v) => { - my_size += ::protobuf::rt::value_size(2, v, ::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 let Some(ref v) = self.row_order.as_ref() { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if let ::std::option::Option::Some(ref v) = self.one_of_index { - match v { - &IndexRowOrder_oneof_one_of_index::index(v) => { - os.write_int32(2, v)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> IndexRowOrder { - IndexRowOrder::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "row_order", - |m: &IndexRowOrder| { &m.row_order }, - |m: &mut IndexRowOrder| { &mut m.row_order }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( - "index", - IndexRowOrder::has_index, - IndexRowOrder::get_index, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "IndexRowOrder", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static IndexRowOrder { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(IndexRowOrder::new) - } -} - -impl ::protobuf::Clear for IndexRowOrder { - fn clear(&mut self) { - self.row_order.clear(); - self.one_of_index = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for IndexRowOrder { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for IndexRowOrder { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct GridBlock { // message fields @@ -7261,81 +7799,87 @@ static file_descriptor_proto_data: &'static [u8] = b"\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ - id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldContextPayl\ - oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08fiel\ - d_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\ - \x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\n\x10Edi\ - tFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\ - \n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_type\x18\x03\ - \x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\x02\ - \x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\x03\ - \x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05items\ - \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ - RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ - lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ - yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ - \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ - (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ - \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ - \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ - \x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\x12\x19\n\ - \x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\x18\x02\ - \x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xbf\x01\n\x11GridRowsChangeset\ - \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\rinserted_r\ - ows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\x12,\n\x0cd\ - eleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\x0cu\ - pdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"_\n\rIndex\ - RowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrder\ - \x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_i\ - ndex\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nr\ - ow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ - \x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\x12\ - \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\ - \x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ - \x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\ - \x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\ - \x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04nam\ - e\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\ - \x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0\ - R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12InsertFieldPa\ - yload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05fi\ - eld\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ - \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ - \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ - \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ - \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ - \x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPayload\ - \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ - id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0\ - R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfie\ - ld_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06\ - frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\ - \x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\ - \x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\ - \x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one\ - _of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\ - \x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0fMoveIt\ - emPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x17\n\ - \x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\x18\x03\ - \x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\x05R\ - \x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\x02ty\ - \"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ - Id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_i\ - d\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0\ - R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\tMoveField\x10\ - \0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\ - \0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0c\ - SingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Check\ - box\x10\x05b\x06proto3\ + id\x18\x01\x20\x01(\tR\x07fieldId\"\xc6\x01\n\x12GridFieldChangeset\x12\ + \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x124\n\x0finserted_field\ + s\x18\x02\x20\x03(\x0b2\x0b.IndexFieldR\x0einsertedFields\x122\n\x0edele\ + ted_fields\x18\x03\x20\x03(\x0b2\x0b.FieldOrderR\rdeletedFields\x12-\n\ + \x0eupdated_fields\x18\x04\x20\x03(\x0b2\x06.FieldR\rupdatedFields\"R\n\ + \nIndexField\x12\x1c\n\x05field\x18\x01\x20\x01(\x0b2\x06.FieldR\x05fiel\ + d\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_\ + index\"\x90\x01\n\x1aGetEditFieldContextPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_id\x18\x02\x20\x01(\tH\0R\ + \x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfield\ + TypeB\x11\n\x0fone_of_field_id\"q\n\x10EditFieldPayload\x12\x17\n\x07gri\ + d_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01\ + (\tR\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tf\ + ieldType\"|\n\x10EditFieldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ + \tR\x06gridId\x12%\n\ngrid_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridF\ + ield\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\ + \"-\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ + \x05items\"7\n\x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\ + \x0b2\x0b.FieldOrderR\x05items\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\ + \x01\x20\x01(\tR\x05rowId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07b\ + lockId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\ + \x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_fiel\ + d_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\ + \x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFie\ + ldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\ + \x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\ + \x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11Repe\ + atedGridBlock\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05i\ + tems\"U\n\x0eGridBlockOrder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\ + \x07blockId\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrd\ + ers\"_\n\rIndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrd\ + erR\x08rowOrder\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\ + \x0e\n\x0cone_of_index\"\xbf\x01\n\x11GridRowsChangeset\x12\x19\n\x08blo\ + ck_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\rinserted_rows\x18\x02\x20\ + \x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\x12,\n\x0cdeleted_rows\x18\ + \x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\x0cupdated_rows\x18\ + \x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"E\n\tGridBlock\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ + 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ + \"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ + \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\ + \x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepe\ + atedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\ + \n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\ + \x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\ + \x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10\ + CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of\ + _start_row_id\"\xb6\x01\n\x12InsertFieldPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.\ + FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etype\ + OptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartField\ + IdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ + \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ + locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ + \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ + s\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ + \x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ + \x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n\ + .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\ + \x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibi\ + lity\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10ty\ + pe_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of\ + _nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_fro\ + zenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_\ + type_option_data\"\x9c\x01\n\x0fMoveItemPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x17\n\x07item_id\x18\x02\x20\x01(\tR\x06i\ + temId\x12\x1d\n\nfrom_index\x18\x03\x20\x01(\x05R\tfromIndex\x12\x19\n\ + \x08to_index\x18\x04\x20\x01(\x05R\x07toIndex\x12\x1d\n\x02ty\x18\x05\ + \x20\x01(\x0e2\r.MoveItemTypeR\x02ty\"\x7f\n\rCellChangeset\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ + \x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07field\ + Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data*\ + *\n\x0cMoveItemType\x12\r\n\tMoveField\x10\0\x12\x0b\n\x07MoveRow\x10\ + \x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\ + \x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\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 eca5a5f0ea..acf01a229c 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,6 +17,16 @@ message Field { message FieldOrder { string field_id = 1; } +message GridFieldChangeset { + string grid_id = 1; + repeated IndexField inserted_fields = 2; + repeated FieldOrder deleted_fields = 3; + repeated Field updated_fields = 4; +} +message IndexField { + Field field = 1; + oneof one_of_index { int32 index = 2; }; +} message GetEditFieldContextPayload { string grid_id = 1; oneof one_of_field_id { string field_id = 2; }; @@ -58,16 +68,16 @@ message GridBlockOrder { string block_id = 1; repeated RowOrder row_orders = 2; } +message IndexRowOrder { + RowOrder row_order = 1; + oneof one_of_index { int32 index = 2; }; +} message GridRowsChangeset { string block_id = 1; repeated IndexRowOrder inserted_rows = 2; repeated RowOrder deleted_rows = 3; repeated RowOrder updated_rows = 4; } -message IndexRowOrder { - RowOrder row_order = 1; - oneof one_of_index { int32 index = 2; }; -} message GridBlock { string id = 1; repeated RowOrder row_orders = 2; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index dc67e79d33..e39798a33a 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -82,19 +82,23 @@ impl GridMetaPad { ) } - pub fn duplicate_field(&mut self, field_id: &str) -> CollaborateResult> { - self.modify_grid( - |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { - None => Ok(None), - Some(index) => { - let mut duplicate_field_meta = grid_meta.fields[index].clone(); - duplicate_field_meta.id = gen_field_id(); - duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); - grid_meta.fields.insert(index + 1, duplicate_field_meta); - Ok(Some(())) - } - }, - ) + pub fn duplicate_field(&mut self, field_id: &str) -> CollaborateResult<(Option, Option)> { + let mut field_meta = None; + let changeset = + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + let mut duplicate_field_meta = grid_meta.fields[index].clone(); + duplicate_field_meta.id = gen_field_id(); + duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); + field_meta = Some(duplicate_field_meta.clone()); + grid_meta.fields.insert(index + 1, duplicate_field_meta); + Ok(Some(())) + } + }, + )?; + Ok((changeset, field_meta)) } pub fn switch_to_field( From fd9e13bf4b19c41e99768ff1b63975cbb3c7eb70 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 14 Apr 2022 13:29:42 +0800 Subject: [PATCH 151/179] chore: refactor grid field listener --- .../app_flowy/lib/startup/deps_resolver.dart | 11 +- .../lib/startup/tasks/app_widget.dart | 10 +- .../grid/cell_bloc/date_cell_bloc.dart | 4 +- .../grid/cell_bloc/number_cell_bloc.dart | 4 +- .../grid/cell_bloc/selection_cell_bloc.dart | 4 +- .../grid/cell_bloc/selection_editor_bloc.dart | 4 +- .../grid/field/field_cell_bloc.dart | 4 +- .../grid/field/field_listener.dart | 4 +- .../application/grid/field/grid_listenr.dart | 4 +- .../workspace/application/grid/grid_bloc.dart | 120 +++-------- .../application/grid/grid_header_bloc.dart | 76 +++++++ .../application/grid/grid_service.dart | 176 +++++++++++++++ .../workspace/application/grid/prelude.dart | 1 + .../application/grid/row/row_bloc.dart | 21 +- .../grid/setting/property_bloc.dart | 2 +- .../plugins/grid/src/grid_page.dart | 24 ++- .../grid/src/widgets/header/grid_header.dart | 84 ++++++-- .../grid/src/widgets/row/grid_row.dart | 5 +- .../flowy-grid-data-model/grid.pb.dart | 13 -- .../flowy-grid-data-model/grid.pbjson.dart | 7 +- .../src/services/folder_editor.rs | 28 +-- .../flowy-grid/src/services/grid_editor.rs | 112 +++++----- .../src/entities/grid.rs | 13 +- .../src/protobuf/model/grid.rs | 203 ++++++++---------- .../src/protobuf/proto/grid.proto | 2 +- .../src/client_grid/grid_meta_pad.rs | 53 ++--- 26 files changed, 609 insertions(+), 380 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 5c835ce217..cb685cd7b2 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -150,9 +150,16 @@ void _resolveGridDeps(GetIt getIt) { (view, _) => GridBloc(view: view), ); - getIt.registerFactoryParam( - (data, _) => RowBloc( + getIt.registerFactoryParam( + (data, fieldCache) => RowBloc( rowData: data, + fieldCache: fieldCache, + ), + ); + + getIt.registerFactoryParam>( + (gridId, fields) => GridHeaderBloc( + data: GridHeaderData(gridId: gridId, fields: fields), ), ); diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 12e88949a0..1747cfd8ec 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -123,9 +123,9 @@ class ApplicationBlocObserver extends BlocObserver { super.onError(bloc, error, stackTrace); } - @override - void onEvent(Bloc bloc, Object? event) { - Log.debug("$event"); - super.onEvent(bloc, event); - } + // @override + // void onEvent(Bloc bloc, Object? event) { + // Log.debug("$event"); + // super.onEvent(bloc, event); + // } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index ff8d7d012e..f235b47e4a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -13,12 +13,12 @@ part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { final CellService _service; final CellListener _cellListener; - final FieldListener _fieldListener; + final SingleFieldListener _fieldListener; DateCellBloc({required CellData cellData}) : _service = CellService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), - _fieldListener = FieldListener(fieldId: cellData.field.id), + _fieldListener = SingleFieldListener(fieldId: cellData.field.id), super(DateCellState.initial(cellData)) { on( (event, emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index e61e8f96a6..a145305bbe 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -13,13 +13,13 @@ part 'number_cell_bloc.freezed.dart'; class NumberCellBloc extends Bloc { final CellService _service; final CellListener _cellListener; - final FieldListener _fieldListener; + final SingleFieldListener _fieldListener; NumberCellBloc({ required CellData cellData, }) : _service = CellService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), - _fieldListener = FieldListener(fieldId: cellData.field.id), + _fieldListener = SingleFieldListener(fieldId: cellData.field.id), super(NumberCellState.initial(cellData)) { on( (event, emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index d77280085e..b7e472e181 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -13,13 +13,13 @@ part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { final SelectOptionService _service; final CellListener _cellListener; - final FieldListener _fieldListener; + final SingleFieldListener _fieldListener; SelectionCellBloc({ required CellData cellData, }) : _service = SelectOptionService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), - _fieldListener = FieldListener(fieldId: cellData.field.id), + _fieldListener = SingleFieldListener(fieldId: cellData.field.id), super(SelectionCellState.initial(cellData)) { on( (event, emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 5b6ba78bd5..59510298a7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -13,7 +13,7 @@ part 'selection_editor_bloc.freezed.dart'; class SelectOptionEditorBloc extends Bloc { final SelectOptionService _selectOptionService; - final FieldListener _fieldListener; + final SingleFieldListener _fieldListener; final CellListener _cellListener; Timer? _delayOperation; @@ -22,7 +22,7 @@ class SelectOptionEditorBloc extends Bloc options, required List selectedOptions, }) : _selectOptionService = SelectOptionService(), - _fieldListener = FieldListener(fieldId: cellData.field.id), + _fieldListener = SingleFieldListener(fieldId: cellData.field.id), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(SelectOptionEditorState.initial(cellData, options, selectedOptions)) { on( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart index 376b98f19a..026be9a780 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -9,12 +9,12 @@ import 'dart:async'; part 'field_cell_bloc.freezed.dart'; class FieldCellBloc extends Bloc { - final FieldListener _fieldListener; + final SingleFieldListener _fieldListener; final FieldService _fieldService; FieldCellBloc({ required GridFieldCellContext cellContext, - }) : _fieldListener = FieldListener(fieldId: cellContext.field.id), + }) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id), _fieldService = FieldService(gridId: cellContext.gridId), super(FieldCellState.initial(cellContext)) { on( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart index ed09ca9b82..450d88fe18 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart @@ -9,12 +9,12 @@ import 'package:app_flowy/core/notification_helper.dart'; typedef UpdateFieldNotifiedValue = Either; -class FieldListener { +class SingleFieldListener { final String fieldId; PublishNotifier updateFieldNotifier = PublishNotifier(); GridNotificationListener? _listener; - FieldListener({required this.fieldId}); + SingleFieldListener({required this.fieldId}); void start() { _listener = GridNotificationListener( diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index 434b343d8d..d823207f83 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -typedef UpdateFieldNotifiedValue = Either, FlowyError>; +typedef UpdateFieldNotifiedValue = Either; class GridFieldsListener { final String gridId; @@ -26,7 +26,7 @@ class GridFieldsListener { switch (ty) { case GridNotification.DidUpdateGrid: result.fold( - (payload) => updateFieldsNotifier.value = left(RepeatedField.fromBuffer(payload).items), + (payload) => updateFieldsNotifier.value = left(GridFieldChangeset.fromBuffer(payload)), (error) => updateFieldsNotifier.value = right(error), ); break; 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 30cb7c9a29..abdf73acbc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -17,18 +17,22 @@ class GridBloc extends Bloc { final GridService _gridService; final GridListener _gridListener; final GridFieldsListener _fieldListener; + final GridFieldCache fieldCache; + final GridRowCache _rowCache; GridBloc({required View view}) : _fieldListener = GridFieldsListener(gridId: view.id), _gridService = GridService(gridId: view.id), _gridListener = GridListener(gridId: view.id), + fieldCache = GridFieldCache(), + _rowCache = GridRowCache(gridId: view.id), super(GridState.initial(view.id)) { on( (event, emit) async { await event.map( initial: (InitialGrid value) async { - await _initGrid(emit); _startListening(); + await _loadGrid(emit); }, createRow: (_CreateRow value) { _gridService.createRow(); @@ -37,11 +41,9 @@ class GridBloc extends Bloc { emit(state.copyWith(rows: value.rows, listState: value.listState)); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - final rows = state.rows.map((row) => row.copyWith(fields: value.fields)).toList(); emit(state.copyWith( - rows: rows, + rows: _rowCache.rows, fields: value.fields, - listState: const GridListState.reload(), )); }, ); @@ -57,35 +59,39 @@ class GridBloc extends Bloc { return super.close(); } - Future _initGrid(Emitter emit) async { + void _startListening() { + fieldCache.addListener((fields) { + _rowCache.updateFields(fields); + }); + _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( - (fields) => add(GridEvent.didReceiveFieldUpdate(fields)), + (changeset) { + fieldCache.applyChangeset(changeset); + add(GridEvent.didReceiveFieldUpdate(List.from(fieldCache.fields))); + }, (err) => Log.error(err), ); }); _fieldListener.start(); - await _loadGrid(emit); - } - - void _startListening() { _gridListener.rowsUpdateNotifier.addPublishListener((result) { - result.fold((gridBlockChangeset) { - for (final changeset in gridBlockChangeset) { - if (changeset.insertedRows.isNotEmpty) { - _insertRows(changeset.insertedRows); - } + result.fold( + (changesets) { + for (final changeset in changesets) { + _rowCache + .deleteRows(changeset.deletedRows) + .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(_rowCache.rows, listState))); - if (changeset.deletedRows.isNotEmpty) { - _deleteRows(changeset.deletedRows); - } + _rowCache + .insertRows(changeset.insertedRows) + .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(_rowCache.rows, listState))); - if (changeset.updatedRows.isNotEmpty) { - _updateRows(changeset.updatedRows); + _rowCache.updateRows(changeset.updatedRows); } - } - }, (err) => Log.error(err)); + }, + (err) => Log.error(err), + ); }); _gridListener.start(); } @@ -105,10 +111,13 @@ class GridBloc extends Bloc { return Future( () => result.fold( (fields) { + fieldCache.fields = fields.items; + _rowCache.updateWithBlock(grid.blockOrders); + emit(state.copyWith( grid: Some(grid), - fields: fields.items, - rows: _buildRows(grid.blockOrders, fields.items), + fields: fieldCache.fields, + rows: _rowCache.rows, loadingState: GridLoadingState.finish(left(unit)), )); }, @@ -116,60 +125,6 @@ class GridBloc extends Bloc { ), ); } - - void _deleteRows(List deletedRows) { - final List rows = []; - final List> deletedIndex = []; - final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; - state.rows.asMap().forEach((index, value) { - if (deletedRowMap[value.rowId] == null) { - rows.add(value); - } else { - deletedIndex.add(Tuple2(index, value)); - } - }); - - add(GridEvent.didReceiveRowUpdate(rows, GridListState.delete(deletedIndex))); - } - - void _insertRows(List createdRows) { - final List rows = List.from(state.rows); - List insertIndexs = []; - for (final newRow in createdRows) { - if (newRow.hasIndex()) { - insertIndexs.add(newRow.index); - rows.insert(newRow.index, _toRowData(newRow.rowOrder)); - } else { - insertIndexs.add(rows.length); - rows.add(_toRowData(newRow.rowOrder)); - } - } - add(GridEvent.didReceiveRowUpdate(rows, GridListState.insert(insertIndexs))); - } - - void _updateRows(List updatedRows) { - final List rows = List.from(state.rows); - final List updatedIndexs = []; - for (final updatedRow in updatedRows) { - final index = rows.indexWhere((row) => row.rowId == updatedRow.rowId); - if (index != -1) { - rows.removeAt(index); - rows.insert(index, _toRowData(updatedRow)); - updatedIndexs.add(index); - } - } - add(GridEvent.didReceiveRowUpdate(rows, const GridListState.reload())); - } - - List _buildRows(List blockOrders, List fields) { - return blockOrders.expand((blockOrder) => blockOrder.rowOrders).map((rowOrder) { - return RowData.fromBlockRow(state.gridId, rowOrder, fields); - }).toList(); - } - - RowData _toRowData(RowOrder rowOrder) { - return RowData.fromBlockRow(state.gridId, rowOrder, state.fields); - } } @freezed @@ -197,7 +152,7 @@ class GridState with _$GridState { grid: none(), gridId: gridId, loadingState: const _Loading(), - listState: const _Reload(), + listState: const InitialListState(), ); } @@ -206,10 +161,3 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.loading() = _Loading; const factory GridLoadingState.finish(Either successOrFail) = _Finish; } - -@freezed -class GridListState with _$GridListState { - const factory GridListState.insert(List indexs) = _Insert; - const factory GridListState.delete(List> indexs) = _Delete; - const factory GridListState.reload() = _Reload; -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart new file mode 100644 index 0000000000..18086ce6d9 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -0,0 +1,76 @@ +import 'package:app_flowy/workspace/application/grid/data.dart'; +import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field/field_service.dart'; +import 'grid_service.dart'; + +part 'grid_header_bloc.freezed.dart'; + +class GridHeaderBloc extends Bloc { + final FieldService _fieldService; + final GridFieldCache _fieldCache; + final GridFieldsListener _fieldListener; + + GridHeaderBloc({ + required GridHeaderData data, + }) : _fieldListener = GridFieldsListener(gridId: data.gridId), + _fieldService = FieldService(gridId: data.gridId), + _fieldCache = GridFieldCache(), + super(GridHeaderState.initial(data.fields)) { + _fieldCache.fields = data.fields; + + on( + (event, emit) async { + await event.map( + initial: (_InitialHeader value) async { + _startListening(); + }, + didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { + value.fields.retainWhere((field) => field.visibility); + emit(state.copyWith(fields: value.fields)); + }, + ); + }, + ); + } + + Future _startListening() async { + _fieldListener.updateFieldsNotifier.addPublishListener((result) { + result.fold( + (changeset) { + _fieldCache.applyChangeset(changeset); + add(GridHeaderEvent.didReceiveFieldUpdate(List.from(_fieldCache.fields))); + }, + (err) => Log.error(err), + ); + }); + + _fieldListener.start(); + } + + @override + Future close() async { + await _fieldListener.stop(); + return super.close(); + } +} + +@freezed +class GridHeaderEvent with _$GridHeaderEvent { + const factory GridHeaderEvent.initial() = _InitialHeader; + const factory GridHeaderEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; +} + +@freezed +class GridHeaderState with _$GridHeaderState { + const factory GridHeaderState({required List fields}) = _GridHeaderState; + + factory GridHeaderState.initial(List fields) { + fields.retainWhere((field) => field.visibility); + return GridHeaderState(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 a150b234d0..f596d90be2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,6 +3,11 @@ 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:flutter/foundation.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; + +part 'grid_service.freezed.dart'; class GridService { final String gridId; @@ -35,3 +40,174 @@ class GridService { return FolderEventCloseView(request).send(); } } + +class FieldsNotifier extends ChangeNotifier { + List _fields = []; + + set fields(List fields) { + _fields = fields; + notifyListeners(); + } + + List get fields => _fields; +} + +class GridFieldCache { + final FieldsNotifier _fieldNotifier = FieldsNotifier(); + GridFieldCache(); + + void applyChangeset(GridFieldChangeset changeset) { + _removeFields(changeset.deletedFields); + _insertFields(changeset.insertedFields); + _updateFields(changeset.updatedFields); + } + + List get fields => _fieldNotifier.fields; + + set fields(List fields) { + _fieldNotifier.fields = fields; + } + + set onFieldChanged(void Function(List) onChanged) { + _fieldNotifier.addListener(() => onChanged(fields)); + } + + void addListener(void Function(List) onFieldChanged) { + _fieldNotifier.addListener(() => onFieldChanged(fields)); + } + + void _removeFields(List deletedFields) { + if (deletedFields.isEmpty) { + return; + } + final List fields = List.from(_fieldNotifier.fields); + final Map deletedFieldMap = { + for (var fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder + }; + + fields.retainWhere((field) => (deletedFieldMap[field.id] == null)); + _fieldNotifier.fields = fields; + } + + void _insertFields(List insertedFields) { + if (insertedFields.isEmpty) { + return; + } + final List fields = List.from(_fieldNotifier.fields); + for (final indexField in insertedFields) { + if (fields.length > indexField.index) { + fields.removeAt(indexField.index); + fields.insert(indexField.index, indexField.field_1); + } else { + fields.add(indexField.field_1); + } + } + _fieldNotifier.fields = fields; + } + + void _updateFields(List updatedFields) { + if (updatedFields.isEmpty) { + return; + } + final List fields = List.from(_fieldNotifier.fields); + for (final updatedField in updatedFields) { + final index = fields.indexWhere((field) => field.id == updatedField.id); + if (index != -1) { + fields.removeAt(index); + fields.insert(index, updatedField); + } + } + _fieldNotifier.fields = fields; + } +} + +class GridRowCache { + final String gridId; + List _fields = []; + List _rows = []; + + GridRowCache({required this.gridId}); + + List get rows => _rows; + + void updateWithBlock(List blocks) { + _rows = blocks.expand((block) => block.rowOrders).map((rowOrder) { + return RowData.fromBlockRow(gridId, rowOrder, _fields); + }).toList(); + } + + void updateFields(List fields) { + if (fields.isEmpty) { + return; + } + + _fields = fields; + _rows = _rows.map((row) => row.copyWith(fields: fields)).toList(); + } + + Option deleteRows(List deletedRows) { + if (deletedRows.isEmpty) { + return none(); + } + + final List newRows = []; + final List> deletedIndex = []; + final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; + _rows.asMap().forEach((index, value) { + if (deletedRowMap[value.rowId] == null) { + newRows.add(value); + } else { + deletedIndex.add(Tuple2(index, value)); + } + }); + _rows = newRows; + + return Some(GridListState.delete(deletedIndex)); + } + + Option insertRows(List createdRows) { + if (createdRows.isEmpty) { + return none(); + } + + List insertIndexs = []; + for (final newRow in createdRows) { + if (newRow.hasIndex()) { + insertIndexs.add(newRow.index); + _rows.insert(newRow.index, _toRowData(newRow.rowOrder)); + } else { + insertIndexs.add(_rows.length); + _rows.add(_toRowData(newRow.rowOrder)); + } + } + + return Some(GridListState.insert(insertIndexs)); + } + + void updateRows(List updatedRows) { + if (updatedRows.isEmpty) { + return; + } + + final List updatedIndexs = []; + for (final updatedRow in updatedRows) { + final index = _rows.indexWhere((row) => row.rowId == updatedRow.rowId); + if (index != -1) { + _rows.removeAt(index); + _rows.insert(index, _toRowData(updatedRow)); + updatedIndexs.add(index); + } + } + } + + RowData _toRowData(RowOrder rowOrder) { + return RowData.fromBlockRow(gridId, rowOrder, _fields); + } +} + +@freezed +class GridListState with _$GridListState { + const factory GridListState.insert(List indexs) = _Insert; + const factory GridListState.delete(List> indexs) = _Delete; + const factory GridListState.initial() = InitialListState; +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 3fd24f8785..7df38179ac 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -3,6 +3,7 @@ export 'row/row_bloc.dart'; export 'row/row_service.dart'; export 'grid_service.dart'; export 'data.dart'; +export 'grid_header_bloc.dart'; // Field export 'field/field_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 6c0037d289..ec9b8ff04d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -17,18 +17,18 @@ typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { final RowService _rowService; final RowListener _rowlistener; - final GridFieldsListener _fieldListener; + final GridFieldCache _fieldCache; - RowBloc({required RowData rowData}) + RowBloc({required RowData rowData, required GridFieldCache fieldCache}) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), - _fieldListener = GridFieldsListener(gridId: rowData.gridId), + _fieldCache = fieldCache, _rowlistener = RowListener(rowId: rowData.rowId), super(RowState.initial(rowData)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async { - _startListening(); + await _startListening(); await _loadRow(emit); }, createRow: (_CreateRow value) { @@ -69,7 +69,6 @@ class RowBloc extends Bloc { @override Future close() async { await _rowlistener.stop(); - await _fieldListener.stop(); return super.close(); } @@ -81,15 +80,13 @@ class RowBloc extends Bloc { ); }); - _fieldListener.updateFieldsNotifier.addPublishListener((result) { - result.fold( - (fields) => add(RowEvent.didReceiveFieldUpdate(fields)), - (err) => Log.error(err), - ); + _fieldCache.addListener((fields) { + if (!isClosed) { + add(RowEvent.didReceiveFieldUpdate(fields)); + } }); _rowlistener.start(); - _fieldListener.start(); } Future _loadRow(Emitter emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index 66de503321..140aa388cd 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -50,7 +50,7 @@ class GridPropertyBloc extends Bloc { _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( (fields) { - add(GridPropertyEvent.didReceiveFieldUpdate(fields)); + // add(GridPropertyEvent.didReceiveFieldUpdate(fields)); }, (err) => Log.error(err), ); 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 804ffff685..cb1cb1c888 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 @@ -150,11 +150,7 @@ class _GridHeader extends StatelessWidget { @override Widget build(BuildContext context) { - return SliverPersistentHeader( - delegate: GridHeaderSliverAdaptor(gridId: gridId, fields: List.from(fields)), - floating: true, - pinned: true, - ); + return GridHeaderSliverAdaptor(gridId: gridId, fields: fields); } } @@ -174,10 +170,13 @@ class _GridRows extends StatelessWidget { }, delete: (value) { for (final index in value.indexs) { - _key.currentState?.removeItem(index.value1, (context, animation) => _renderRow(index.value2, animation)); + _key.currentState?.removeItem( + index.value1, + (context, animation) => _renderRow(context, index.value2, animation), + ); } }, - reload: (updatedIndexs) {}, + initial: (updatedIndexs) {}, ); }, buildWhen: (previous, current) => false, @@ -187,17 +186,22 @@ class _GridRows extends StatelessWidget { initialItemCount: context.read().state.rows.length, itemBuilder: (BuildContext context, int index, Animation animation) { final rowData = context.read().state.rows[index]; - return _renderRow(rowData, animation); + return _renderRow(context, rowData, animation); }, ); }, ); } - Widget _renderRow(RowData rowData, Animation animation) { + Widget _renderRow(BuildContext context, RowData rowData, Animation animation) { + final fieldCache = context.read().fieldCache; return SizeTransition( sizeFactor: animation, - child: GridRowWidget(data: rowData, key: ValueKey(rowData.rowId)), + child: GridRowWidget( + data: rowData, + fieldCache: fieldCache, + key: ValueKey(rowData.rowId), + ), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index c387ecd4e2..3893ac7784 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -12,32 +12,38 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_editor.dart'; import 'field_cell.dart'; -class GridHeaderSliverAdaptor extends SliverPersistentHeaderDelegate { +class GridHeaderSliverAdaptor extends StatelessWidget { final String gridId; final List fields; - GridHeaderSliverAdaptor({required this.gridId, required this.fields}); + const GridHeaderSliverAdaptor({required this.gridId, required this.fields, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: gridId, param2: fields)..add(const GridHeaderEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + return SliverPersistentHeader( + delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: fields), + floating: true, + pinned: true, + ); + }, + ), + ); + } +} + +class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate { + final String gridId; + final List fields; + + SliverHeaderDelegateImplementation({required this.gridId, required this.fields}); @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - final cells = fields.map( - (field) => GridFieldCell( - GridFieldCellContext(gridId: gridId, field: field), - ), - ); - - return Container( - color: Colors.white, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _CellLeading(), - ...cells, - _CellTrailing(gridId: gridId), - ], - key: ObjectKey(fields), - ), - ); + return _GridHeader(gridId: gridId, fields: fields, key: ObjectKey(fields)); } @override @@ -48,13 +54,49 @@ class GridHeaderSliverAdaptor extends SliverPersistentHeaderDelegate { @override bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { - if (oldDelegate is GridHeaderSliverAdaptor) { + if (oldDelegate is SliverHeaderDelegateImplementation) { return fields.length != oldDelegate.fields.length; } return true; } } +class _GridHeader extends StatelessWidget { + final String gridId; + final List fields; + + const _GridHeader({ + Key? key, + required this.gridId, + required this.fields, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocBuilder( + builder: (context, state) { + final cells = state.fields + .map((field) => GridFieldCellContext(gridId: gridId, field: field)) + .map((ctx) => GridFieldCell(ctx, key: ValueKey(ctx.field.id))) + .toList(); + + return Container( + color: theme.surface, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _CellLeading(), + ...cells, + _CellTrailing(gridId: gridId), + ], + ), + ); + }, + ); + } +} + class _CellLeading extends StatelessWidget { const _CellLeading({Key? key}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index baeed922d7..5528818a58 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -13,7 +13,8 @@ import 'row_action_sheet.dart'; class GridRowWidget extends StatefulWidget { final RowData data; - const GridRowWidget({required this.data, Key? key}) : super(key: key); + final GridFieldCache fieldCache; + const GridRowWidget({required this.data, required this.fieldCache, Key? key}) : super(key: key); @override State createState() => _GridRowWidgetState(); @@ -25,7 +26,7 @@ class _GridRowWidgetState extends State { @override void initState() { - _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); + _rowBloc = getIt(param1: widget.data, param2: widget.fieldCache)..add(const RowEvent.initial()); _rowStateNotifier = _RegionStateNotifier(); super.initState(); } 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 1212cb506e..8c01e7c1bc 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 @@ -325,18 +325,8 @@ class GridFieldChangeset extends $pb.GeneratedMessage { $core.List get updatedFields => $_getList(3); } -enum IndexField_OneOfIndex { - index_, - notSet -} - class IndexField extends $pb.GeneratedMessage { - static const $core.Map<$core.int, IndexField_OneOfIndex> _IndexField_OneOfIndexByTag = { - 2 : IndexField_OneOfIndex.index_, - 0 : IndexField_OneOfIndex.notSet - }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'IndexField', createEmptyInstance: create) - ..oo(0, [2]) ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create) ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'index', $pb.PbFieldType.O3) ..hasRequiredFields = false @@ -377,9 +367,6 @@ class IndexField extends $pb.GeneratedMessage { static IndexField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); static IndexField? _defaultInstance; - IndexField_OneOfIndex whichOneOfIndex() => _IndexField_OneOfIndexByTag[$_whichOneof(0)]!; - void clearOneOfIndex() => clearField($_whichOneof(0)); - @$pb.TagNumber(1) Field get field_1 => $_getN(0); @$pb.TagNumber(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 a5d8fab78f..624e31c392 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 @@ -90,15 +90,12 @@ const IndexField$json = const { '1': 'IndexField', '2': const [ const {'1': 'field', '3': 1, '4': 1, '5': 11, '6': '.Field', '10': 'field'}, - const {'1': 'index', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'index'}, - ], - '8': const [ - const {'1': 'one_of_index'}, + const {'1': 'index', '3': 2, '4': 1, '5': 5, '10': 'index'}, ], }; /// Descriptor for `IndexField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List indexFieldDescriptor = $convert.base64Decode('CgpJbmRleEZpZWxkEhwKBWZpZWxkGAEgASgLMgYuRmllbGRSBWZpZWxkEhYKBWluZGV4GAIgASgFSABSBWluZGV4Qg4KDG9uZV9vZl9pbmRleA=='); +final $typed_data.Uint8List indexFieldDescriptor = $convert.base64Decode('CgpJbmRleEZpZWxkEhwKBWZpZWxkGAEgASgLMgYuRmllbGRSBWZpZWxkEhQKBWluZGV4GAIgASgFUgVpbmRleA=='); @$core.Deprecated('Use getEditFieldContextPayloadDescriptor instead') const GetEditFieldContextPayload$json = const { '1': 'GetEditFieldContextPayload', 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 99867fb484..b7c30919b6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -24,7 +24,7 @@ pub struct ClientFolderEditor { pub(crate) folder_id: FolderId, pub(crate) folder: Arc>, rev_manager: Arc, - ws_manager: Arc, + // ws_manager: Arc, } impl ClientFolderEditor { @@ -40,14 +40,14 @@ impl ClientFolderEditor { }); let folder = Arc::new(RwLock::new(rev_manager.load::(Some(cloud)).await?)); let rev_manager = Arc::new(rev_manager); - let ws_manager = make_folder_ws_manager( - user_id, - folder_id.as_ref(), - rev_manager.clone(), - web_socket, - folder.clone(), - ) - .await; + // let ws_manager = make_folder_ws_manager( + // user_id, + // folder_id.as_ref(), + // rev_manager.clone(), + // web_socket, + // folder.clone(), + // ) + // .await; let user_id = user_id.to_owned(); let folder_id = folder_id.to_owned(); @@ -56,15 +56,15 @@ impl ClientFolderEditor { folder_id, folder, rev_manager, - ws_manager, + // ws_manager, }) } pub async fn receive_ws_data(&self, data: ServerRevisionWSData) -> FlowyResult<()> { - let _ = self.ws_manager.ws_passthrough_tx.send(data).await.map_err(|e| { - let err_msg = format!("{} passthrough error: {}", self.folder_id, e); - FlowyError::internal().context(err_msg) - })?; + // let _ = self.ws_manager.ws_passthrough_tx.send(data).await.map_err(|e| { + // let err_msg = format!("{} passthrough error: {}", self.folder_id, e); + // FlowyError::internal().context(err_msg) + // })?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 8425097f69..5cd4ebca87 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -59,9 +59,9 @@ impl ClientGridEditor { grid_id, } = params; let field_id = field.id.clone(); - let _ = self - .modify(|grid| { - if grid.contain_field(&field.id) { + if self.contain_field(&field_id).await { + let _ = self + .modify(|grid| { let deserializer = TypeOptionJsonDeserializer(field.field_type.clone()); let changeset = FieldChangesetParams { field_id: field.id, @@ -74,17 +74,22 @@ impl ClientGridEditor { width: Some(field.width), type_option_data: Some(type_option_data), }; - Ok(grid.update_field(changeset, deserializer)?) - } else { - // let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type); + Ok(grid.update_field_meta(changeset, deserializer)?) + }) + .await?; + let _ = self.notify_grid_did_update_field(&field_id).await?; + } else { + let _ = self + .modify(|grid| { let builder = type_option_builder_from_bytes(type_option_data, &field.field_type); let field_meta = FieldBuilder::from_field(field, builder).build(); - Ok(grid.create_field(field_meta, start_field_id)?) - } - }) - .await?; - let _ = self.notify_did_update_grid().await?; - let _ = self.notify_did_update_field(&field_id).await?; + + Ok(grid.create_field_meta(field_meta, start_field_id)?) + }) + .await?; + let _ = self.notify_grid_did_insert_field(&field_id).await?; + } + Ok(()) } @@ -100,29 +105,31 @@ impl ClientGridEditor { pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let field_id = params.field_id.clone(); - let json_deserializer = match self.pad.read().await.get_field(params.field_id.as_str()) { + let json_deserializer = match self.pad.read().await.get_field_meta(params.field_id.as_str()) { None => return Err(ErrorCode::FieldDoesNotExist.into()), - Some(field_meta) => TypeOptionJsonDeserializer(field_meta.field_type.clone()), + Some((_, field_meta)) => TypeOptionJsonDeserializer(field_meta.field_type.clone()), }; let _ = self - .modify(|grid| Ok(grid.update_field(params, json_deserializer)?)) + .modify(|grid| Ok(grid.update_field_meta(params, json_deserializer)?)) .await?; - let _ = self.notify_did_update_grid().await?; - let _ = self.notify_did_update_field(&field_id).await?; + + let _ = self.notify_grid_did_update_field(&field_id).await?; Ok(()) } pub async fn replace_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { let field_id = field_meta.id.clone(); - let _ = self.modify(|pad| Ok(pad.replace_field(field_meta)?)).await?; - let _ = self.notify_did_update_field(&field_id).await?; + let _ = self.modify(|pad| Ok(pad.replace_field_meta(field_meta)?)).await?; + let _ = self.notify_grid_did_update_field(&field_id).await?; Ok(()) } pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; - let _ = self.notify_did_update_grid().await?; + let _ = self.modify(|grid| Ok(grid.delete_field_meta(field_id)?)).await?; + let field_order = FieldOrder::from(field_id); + let notified_changeset = GridFieldChangeset::delete(&self.grid_id, vec![field_order]); + let _ = self.notify_did_update_grid(notified_changeset).await?; Ok(()) } @@ -145,27 +152,24 @@ impl ClientGridEditor { let _ = self .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) .await?; - let _ = self.notify_did_update_grid().await?; - let _ = self.notify_did_update_field(field_id).await?; + + let _ = self.notify_grid_did_update_field(&field_id).await?; + Ok(()) } pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> { - let mut duplicated_field_meta = None; + let duplicated_field_id = gen_field_id(); let _ = self - .modify(|grid| { - let (changeset, field_meta) = grid.duplicate_field(field_id)?; - duplicated_field_meta = field_meta; - Ok(changeset) - }) + .modify(|grid| Ok(grid.duplicate_field_meta(field_id, &duplicated_field_id)?)) .await?; - let _ = self.notify_did_update_grid().await?; + let _ = self.notify_grid_did_insert_field(field_id).await?; Ok(()) } pub async fn get_field_meta(&self, field_id: &str) -> Option { - let field_meta = self.pad.read().await.get_field(field_id)?.clone(); + let field_meta = self.pad.read().await.get_field_meta(field_id)?.1.clone(); Some(field_meta) } @@ -310,12 +314,12 @@ impl ClientGridEditor { let cell_data_changeset = changeset.data.unwrap(); let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?; tracing::trace!("{}: {:?}", &changeset.field_id, cell_meta); - match self.pad.read().await.get_field(&changeset.field_id) { + match self.pad.read().await.get_field_meta(&changeset.field_id) { None => { let msg = format!("Field not found with id: {}", &changeset.field_id); Err(FlowyError::internal().context(msg)) } - Some(field_meta) => { + Some((_, field_meta)) => { // Update the changeset.data property with the return value. changeset.data = Some(apply_cell_data_changeset(cell_data_changeset, cell_meta, field_meta)?); let _ = self.block_meta_manager.update_cell(changeset).await?; @@ -334,11 +338,6 @@ impl ClientGridEditor { Ok(grid_blocks) } - // pub async fn get_field_metas(&self, field_ids: Option>) -> FlowyResult> - // where - // T: Into, - // { - pub async fn delete_rows(&self, row_orders: Vec) -> FlowyResult<()> { let changesets = self.block_meta_manager.delete_rows(row_orders).await?; for changeset in changesets { @@ -445,37 +444,40 @@ impl ClientGridEditor { } } - async fn notify_did_update_grid(&self) -> FlowyResult<()> { - // GridFieldChangeset - - let field_metas = self.get_field_metas::(None).await?; - let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); - send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) - .payload(repeated_field) - .send(); - Ok(()) - } - - async fn notify_did_update_grid2(&self, changeset: GridFieldChangeset) -> FlowyResult<()> { - send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) - .payload(changeset) - .send(); + #[tracing::instrument(level = "trace", skip_all, err)] + async fn notify_grid_did_insert_field(&self, field_id: &str) -> FlowyResult<()> { + if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { + let index_field = IndexField::from_field_meta(field_meta, index); + let notified_changeset = GridFieldChangeset::insert(&self.grid_id, vec![index_field]); + let _ = self.notify_did_update_grid(notified_changeset).await?; + } Ok(()) } #[tracing::instrument(level = "trace", skip_all, err)] - async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { + async fn notify_grid_did_update_field(&self, field_id: &str) -> FlowyResult<()> { let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; debug_assert!(field_metas.len() == 1); if let Some(field_meta) = field_metas.pop() { + let updated_field = Field::from(field_meta); + let notified_changeset = GridFieldChangeset::update(&self.grid_id, vec![updated_field.clone()]); + let _ = self.notify_did_update_grid(notified_changeset).await?; + send_dart_notification(field_id, GridNotification::DidUpdateField) - .payload(Field::from(field_meta)) + .payload(updated_field) .send(); } Ok(()) } + + async fn notify_did_update_grid(&self, changeset: GridFieldChangeset) -> FlowyResult<()> { + send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) + .payload(changeset) + .send(); + Ok(()) + } } #[cfg(feature = "flowy_unit_test")] 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 f090cfdc5e..94f46919c1 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -133,8 +133,17 @@ pub struct IndexField { #[pb(index = 1)] pub field: Field, - #[pb(index = 2, one_of)] - pub index: Option, + #[pb(index = 2)] + pub index: i32, +} + +impl IndexField { + pub fn from_field_meta(field_meta: &FieldMeta, index: usize) -> Self { + Self { + field: Field::from(field_meta.clone()), + index: index as i32, + } + } } #[derive(Debug, Default, ProtoBuf)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 46de6cf971..d988ae90c2 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 @@ -1128,8 +1128,7 @@ impl ::protobuf::reflect::ProtobufValue for GridFieldChangeset { pub struct IndexField { // message fields pub field: ::protobuf::SingularPtrField, - // message oneof groups - pub one_of_index: ::std::option::Option, + pub index: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1141,11 +1140,6 @@ impl<'a> ::std::default::Default for &'a IndexField { } } -#[derive(Clone,PartialEq,Debug)] -pub enum IndexField_oneof_one_of_index { - index(i32), -} - impl IndexField { pub fn new() -> IndexField { ::std::default::Default::default() @@ -1188,25 +1182,15 @@ impl IndexField { pub fn get_index(&self) -> i32 { - match self.one_of_index { - ::std::option::Option::Some(IndexField_oneof_one_of_index::index(v)) => v, - _ => 0, - } + self.index } pub fn clear_index(&mut self) { - self.one_of_index = ::std::option::Option::None; - } - - pub fn has_index(&self) -> bool { - match self.one_of_index { - ::std::option::Option::Some(IndexField_oneof_one_of_index::index(..)) => true, - _ => false, - } + self.index = 0; } // Param is passed by value, moved pub fn set_index(&mut self, v: i32) { - self.one_of_index = ::std::option::Option::Some(IndexField_oneof_one_of_index::index(v)) + self.index = v; } } @@ -1231,7 +1215,8 @@ impl ::protobuf::Message for IndexField { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_index = ::std::option::Option::Some(IndexField_oneof_one_of_index::index(is.read_int32()?)); + let tmp = is.read_int32()?; + self.index = tmp; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -1249,12 +1234,8 @@ impl ::protobuf::Message for IndexField { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if let ::std::option::Option::Some(ref v) = self.one_of_index { - match v { - &IndexField_oneof_one_of_index::index(v) => { - my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint); - }, - }; + if self.index != 0 { + my_size += ::protobuf::rt::value_size(2, self.index, ::protobuf::wire_format::WireTypeVarint); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1267,12 +1248,8 @@ impl ::protobuf::Message for IndexField { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - if let ::std::option::Option::Some(ref v) = self.one_of_index { - match v { - &IndexField_oneof_one_of_index::index(v) => { - os.write_int32(2, v)?; - }, - }; + if self.index != 0 { + os.write_int32(2, self.index)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1317,10 +1294,10 @@ impl ::protobuf::Message for IndexField { |m: &IndexField| { &m.field }, |m: &mut IndexField| { &mut m.field }, )); - fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "index", - IndexField::has_index, - IndexField::get_index, + |m: &IndexField| { &m.index }, + |m: &mut IndexField| { &mut m.index }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "IndexField", @@ -1339,7 +1316,7 @@ impl ::protobuf::Message for IndexField { impl ::protobuf::Clear for IndexField { fn clear(&mut self) { self.field.clear(); - self.one_of_index = ::std::option::Option::None; + self.index = 0; self.unknown_fields.clear(); } } @@ -7803,83 +7780,83 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x124\n\x0finserted_field\ s\x18\x02\x20\x03(\x0b2\x0b.IndexFieldR\x0einsertedFields\x122\n\x0edele\ ted_fields\x18\x03\x20\x03(\x0b2\x0b.FieldOrderR\rdeletedFields\x12-\n\ - \x0eupdated_fields\x18\x04\x20\x03(\x0b2\x06.FieldR\rupdatedFields\"R\n\ + \x0eupdated_fields\x18\x04\x20\x03(\x0b2\x06.FieldR\rupdatedFields\"@\n\ \nIndexField\x12\x1c\n\x05field\x18\x01\x20\x01(\x0b2\x06.FieldR\x05fiel\ - d\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_\ - index\"\x90\x01\n\x1aGetEditFieldContextPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_id\x18\x02\x20\x01(\tH\0R\ - \x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfield\ - TypeB\x11\n\x0fone_of_field_id\"q\n\x10EditFieldPayload\x12\x17\n\x07gri\ - d_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01\ - (\tR\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tf\ - ieldType\"|\n\x10EditFieldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ - \tR\x06gridId\x12%\n\ngrid_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridF\ - ield\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\ - \"-\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ - \x05items\"7\n\x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\ - \x0b2\x0b.FieldOrderR\x05items\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\ - \x01\x20\x01(\tR\x05rowId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07b\ - lockId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\ - \x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_fiel\ - d_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\ - \x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFie\ - ldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\ - \x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\ - \x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11Repe\ - atedGridBlock\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05i\ - tems\"U\n\x0eGridBlockOrder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\ - \x07blockId\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrd\ - ers\"_\n\rIndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrd\ - erR\x08rowOrder\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\ - \x0e\n\x0cone_of_index\"\xbf\x01\n\x11GridRowsChangeset\x12\x19\n\x08blo\ - ck_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\rinserted_rows\x18\x02\x20\ - \x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\x12,\n\x0cdeleted_rows\x18\ - \x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\x0cupdated_rows\x18\ - \x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"E\n\tGridBlock\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ - 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ - \"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\ - \x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\ - \x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepe\ - atedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\ - \n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\ - \x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\ - \x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10\ - CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ - \"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of\ - _start_row_id\"\xb6\x01\n\x12InsertFieldPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.\ - FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etype\ - OptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartField\ - IdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ - \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ - locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ - \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ - s\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ - \x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ - \x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n\ - .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\ - \x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibi\ - lity\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10ty\ - pe_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of\ - _nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_fro\ - zenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_\ - type_option_data\"\x9c\x01\n\x0fMoveItemPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\x17\n\x07item_id\x18\x02\x20\x01(\tR\x06i\ - temId\x12\x1d\n\nfrom_index\x18\x03\x20\x01(\x05R\tfromIndex\x12\x19\n\ - \x08to_index\x18\x04\x20\x01(\x05R\x07toIndex\x12\x1d\n\x02ty\x18\x05\ - \x20\x01(\x0e2\r.MoveItemTypeR\x02ty\"\x7f\n\rCellChangeset\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ - \x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07field\ - Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data*\ - *\n\x0cMoveItemType\x12\r\n\tMoveField\x10\0\x12\x0b\n\x07MoveRow\x10\ - \x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\ - \x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\ - \x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + d\x12\x14\n\x05index\x18\x02\x20\x01(\x05R\x05index\"\x90\x01\n\x1aGetEd\ + itFieldContextPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x12\x1b\n\x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_t\ + ype\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field\ + _id\"q\n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\n\ + field_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFie\ + ldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngri\ + d_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_optio\ + n_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ + \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ + edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ + ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ + t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ + \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ + \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ + \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ + .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ + \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ + items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\ + \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"_\n\rIndexRowOrder\x12&\n\ + \trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrder\x12\x16\n\x05i\ + ndex\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_index\"\xbf\x01\ + \n\x11GridRowsChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blo\ + ckId\x123\n\rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0ci\ + nsertedRows\x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0b\ + deletedRows\x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0b\ + updatedRows\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\ + \x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\ + \x07content\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificati\ + onData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08f\ + ield_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\ + \x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07content\ + B\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\ + \x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\ + \n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05va\ + lue\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ + \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ + _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\ + \x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12Ins\ + ertFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type\ + _option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_fie\ + ld_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_fiel\ + d_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFiel\ + dOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_\ + id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\ + \x0b2\x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPa\ + yload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07\ + grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\ + \tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\ + \nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\ + \n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\ + \x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\ + \x01(\x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\ + \x06R\x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\ + \x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\ + \x0e\n\x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0f\ + MoveItemPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \x17\n\x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\ + \x18\x03\x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\ + \x05R\x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\ + \x02ty\"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\ + \x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\ + \x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\ + \tMoveField\x10\0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\ + \x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\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 acf01a229c..45a1af0518 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 @@ -25,7 +25,7 @@ message GridFieldChangeset { } message IndexField { Field field = 1; - oneof one_of_index { int32 index = 2; }; + int32 index = 2; } message GetEditFieldContextPayload { string grid_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index e39798a33a..ebc5483b5b 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -4,11 +4,12 @@ use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ gen_field_id, gen_grid_id, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, - GridBlockMetaChangeset, GridMeta, + GridBlockMetaChangeset, GridMeta, IndexField, }; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; +use futures::StreamExt; use std::sync::Arc; pub type GridMetaDelta = PlainTextDelta; @@ -41,7 +42,7 @@ impl GridMetaPad { } #[tracing::instrument(level = "debug", skip_all, err)] - pub fn create_field( + pub fn create_field_meta( &mut self, new_field_meta: FieldMeta, start_field_id: Option, @@ -70,7 +71,7 @@ impl GridMetaPad { }) } - pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { + pub fn delete_field_meta(&mut self, field_id: &str) -> CollaborateResult> { self.modify_grid( |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { None => Ok(None), @@ -82,23 +83,23 @@ impl GridMetaPad { ) } - pub fn duplicate_field(&mut self, field_id: &str) -> CollaborateResult<(Option, Option)> { - let mut field_meta = None; - let changeset = - self.modify_grid( - |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { - None => Ok(None), - Some(index) => { - let mut duplicate_field_meta = grid_meta.fields[index].clone(); - duplicate_field_meta.id = gen_field_id(); - duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); - field_meta = Some(duplicate_field_meta.clone()); - grid_meta.fields.insert(index + 1, duplicate_field_meta); - Ok(Some(())) - } - }, - )?; - Ok((changeset, field_meta)) + pub fn duplicate_field_meta( + &mut self, + field_id: &str, + duplicated_field_id: &str, + ) -> CollaborateResult> { + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + let mut duplicate_field_meta = grid_meta.fields[index].clone(); + duplicate_field_meta.id = duplicated_field_id.to_string(); + duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name); + grid_meta.fields.insert(index + 1, duplicate_field_meta); + Ok(Some(())) + } + }, + ) } pub fn switch_to_field( @@ -130,7 +131,7 @@ impl GridMetaPad { }) } - pub fn update_field( + pub fn update_field_meta( &mut self, changeset: FieldChangesetParams, deserializer: T, @@ -185,11 +186,15 @@ impl GridMetaPad { }) } - pub fn get_field(&self, field_id: &str) -> Option<&FieldMeta> { - self.grid_meta.fields.iter().find(|field| field.id == field_id) + pub fn get_field_meta(&self, field_id: &str) -> Option<(usize, &FieldMeta)> { + self.grid_meta + .fields + .iter() + .enumerate() + .find(|(_, field)| field.id == field_id) } - pub fn replace_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { + pub fn replace_field_meta(&mut self, field_meta: FieldMeta) -> CollaborateResult> { self.modify_grid( |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_meta.id) { None => Ok(None), From b606c5ba7b19e19f2310dd9b1fa219c1bb8df1f4 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 14 Apr 2022 18:11:28 +0800 Subject: [PATCH 152/179] chore: fix some bugs --- .../app_flowy/lib/startup/deps_resolver.dart | 7 ++-- .../lib/startup/tasks/app_widget.dart | 12 +++---- .../grid/cell_bloc/date_cell_bloc.dart | 6 +++- .../grid/cell_bloc/selection_editor_bloc.dart | 6 +++- .../lib/workspace/application/grid/data.dart | 8 ----- .../grid/field/field_cell_bloc.dart | 6 +++- .../workspace/application/grid/grid_bloc.dart | 19 ++++------ .../application/grid/grid_header_bloc.dart | 36 ++++++------------- .../application/grid/grid_service.dart | 33 +++++++++-------- .../workspace/application/grid/prelude.dart | 1 - .../application/grid/row/row_bloc.dart | 4 +-- .../plugins/grid/src/grid_page.dart | 5 +-- .../grid/src/widgets/header/grid_header.dart | 10 +++--- 13 files changed, 72 insertions(+), 81 deletions(-) delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/data.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index cb685cd7b2..e35f8e7f96 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -157,9 +157,10 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam>( - (gridId, fields) => GridHeaderBloc( - data: GridHeaderData(gridId: gridId, fields: fields), + getIt.registerFactoryParam( + (gridId, fieldCache) => GridHeaderBloc( + gridId: gridId, + fieldCache: fieldCache, ), ); diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 1747cfd8ec..3dba94ce0a 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -113,7 +113,7 @@ class ApplicationBlocObserver extends BlocObserver { // ignore: unnecessary_overrides void onTransition(Bloc bloc, Transition transition) { // Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}"); - // Log.debug("${transition.nextState}"); + Log.debug("${transition.nextState}"); super.onTransition(bloc, transition); } @@ -123,9 +123,9 @@ class ApplicationBlocObserver extends BlocObserver { super.onError(bloc, error, stackTrace); } - // @override - // void onEvent(Bloc bloc, Object? event) { - // Log.debug("$event"); - // super.onEvent(bloc, event); - // } + @override + void onEvent(Bloc bloc, Object? event) { + // Log.debug("$event"); + super.onEvent(bloc, event); + } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index f235b47e4a..7dd58bf5ac 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -62,7 +62,11 @@ class DateCellBloc extends Bloc { _fieldListener.updateFieldNotifier.addPublishListener((result) { result.fold( - (field) => add(DateCellEvent.didReceiveFieldUpdate(field)), + (field) { + if (!isClosed) { + add(DateCellEvent.didReceiveFieldUpdate(field)); + } + }, (err) => Log.error(err), ); }); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 59510298a7..5d2c52dc0e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -144,7 +144,11 @@ class SelectOptionEditorBloc extends Bloc add(SelectOptionEditorEvent.didReceiveFieldUpdate(field)), + (field) { + if (!isClosed) { + add(SelectOptionEditorEvent.didReceiveFieldUpdate(field)); + } + }, (err) => Log.error(err), ); }); diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart deleted file mode 100644 index 7c508a6867..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; - -class GridHeaderData { - final String gridId; - final List fields; - - GridHeaderData({required this.gridId, required this.fields}); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart index 026be9a780..11dd1af530 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -47,7 +47,11 @@ class FieldCellBloc extends Bloc { void _startListening() { _fieldListener.updateFieldNotifier.addPublishListener((result) { result.fold( - (field) => add(FieldCellEvent.didReceiveFieldUpdate(field)), + (field) { + if (!isClosed) { + add(FieldCellEvent.didReceiveFieldUpdate(field)); + } + }, (err) => Log.error(err), ); }); 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 abdf73acbc..882b3eb5b4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -41,10 +41,7 @@ class GridBloc extends Bloc { emit(state.copyWith(rows: value.rows, listState: value.listState)); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - emit(state.copyWith( - rows: _rowCache.rows, - fields: value.fields, - )); + emit(state.copyWith(rows: _rowCache.rows, fields: value.fields)); }, ); }, @@ -56,19 +53,17 @@ class GridBloc extends Bloc { await _gridService.closeGrid(); await _fieldListener.stop(); await _gridListener.stop(); + fieldCache.dispose(); return super.close(); } void _startListening() { - fieldCache.addListener((fields) { - _rowCache.updateFields(fields); - }); - _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( (changeset) { fieldCache.applyChangeset(changeset); - add(GridEvent.didReceiveFieldUpdate(List.from(fieldCache.fields))); + _rowCache.updateFields(fieldCache.unmodifiableFields); + add(GridEvent.didReceiveFieldUpdate(fieldCache.clonedFields)); }, (err) => Log.error(err), ); @@ -111,12 +106,12 @@ class GridBloc extends Bloc { return Future( () => result.fold( (fields) { - fieldCache.fields = fields.items; - _rowCache.updateWithBlock(grid.blockOrders); + fieldCache.clonedFields = fields.items; + _rowCache.updateWithBlock(grid.blockOrders, fieldCache.unmodifiableFields); emit(state.copyWith( grid: Some(grid), - fields: fieldCache.fields, + fields: fieldCache.clonedFields, rows: _rowCache.rows, loadingState: GridLoadingState.finish(left(unit)), )); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart index 18086ce6d9..c7ce6c21f1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -1,6 +1,3 @@ -import 'package:app_flowy/workspace/application/grid/data.dart'; -import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -12,17 +9,13 @@ part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc { final FieldService _fieldService; - final GridFieldCache _fieldCache; - final GridFieldsListener _fieldListener; + final GridFieldCache fieldCache; GridHeaderBloc({ - required GridHeaderData data, - }) : _fieldListener = GridFieldsListener(gridId: data.gridId), - _fieldService = FieldService(gridId: data.gridId), - _fieldCache = GridFieldCache(), - super(GridHeaderState.initial(data.fields)) { - _fieldCache.fields = data.fields; - + required String gridId, + required this.fieldCache, + }) : _fieldService = FieldService(gridId: gridId), + super(GridHeaderState.initial(fieldCache.clonedFields)) { on( (event, emit) async { await event.map( @@ -30,7 +23,6 @@ class GridHeaderBloc extends Bloc { _startListening(); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - value.fields.retainWhere((field) => field.visibility); emit(state.copyWith(fields: value.fields)); }, ); @@ -39,22 +31,15 @@ class GridHeaderBloc extends Bloc { } Future _startListening() async { - _fieldListener.updateFieldsNotifier.addPublishListener((result) { - result.fold( - (changeset) { - _fieldCache.applyChangeset(changeset); - add(GridHeaderEvent.didReceiveFieldUpdate(List.from(_fieldCache.fields))); - }, - (err) => Log.error(err), - ); + fieldCache.listenOnFieldChanged((fields) { + if (!isClosed) { + add(GridHeaderEvent.didReceiveFieldUpdate(fields)); + } }); - - _fieldListener.start(); } @override Future close() async { - await _fieldListener.stop(); return super.close(); } } @@ -70,7 +55,8 @@ class GridHeaderState with _$GridHeaderState { const factory GridHeaderState({required List fields}) = _GridHeaderState; factory GridHeaderState.initial(List fields) { - fields.retainWhere((field) => field.visibility); + // final List newFields = List.from(fields); + // newFields.retainWhere((field) => field.visibility); return GridHeaderState(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 f596d90be2..fc853ef8b7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -62,25 +62,23 @@ class GridFieldCache { _updateFields(changeset.updatedFields); } - List get fields => _fieldNotifier.fields; + UnmodifiableListView get unmodifiableFields => UnmodifiableListView(_fieldNotifier.fields); - set fields(List fields) { - _fieldNotifier.fields = fields; + List get clonedFields => [..._fieldNotifier.fields]; + + set clonedFields(List fields) { + _fieldNotifier.fields = [...fields]; } - set onFieldChanged(void Function(List) onChanged) { - _fieldNotifier.addListener(() => onChanged(fields)); - } - - void addListener(void Function(List) onFieldChanged) { - _fieldNotifier.addListener(() => onFieldChanged(fields)); + void listenOnFieldChanged(void Function(List) onFieldChanged) { + _fieldNotifier.addListener(() => onFieldChanged(clonedFields)); } void _removeFields(List deletedFields) { if (deletedFields.isEmpty) { return; } - final List fields = List.from(_fieldNotifier.fields); + final List fields = _fieldNotifier.fields; final Map deletedFieldMap = { for (var fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder }; @@ -93,7 +91,7 @@ class GridFieldCache { if (insertedFields.isEmpty) { return; } - final List fields = List.from(_fieldNotifier.fields); + final List fields = _fieldNotifier.fields; for (final indexField in insertedFields) { if (fields.length > indexField.index) { fields.removeAt(indexField.index); @@ -109,7 +107,7 @@ class GridFieldCache { if (updatedFields.isEmpty) { return; } - final List fields = List.from(_fieldNotifier.fields); + final List fields = _fieldNotifier.fields; for (final updatedField in updatedFields) { final index = fields.indexWhere((field) => field.id == updatedField.id); if (index != -1) { @@ -119,24 +117,29 @@ class GridFieldCache { } _fieldNotifier.fields = fields; } + + void dispose() { + _fieldNotifier.dispose(); + } } class GridRowCache { final String gridId; - List _fields = []; + UnmodifiableListView _fields = UnmodifiableListView([]); List _rows = []; GridRowCache({required this.gridId}); List get rows => _rows; - void updateWithBlock(List blocks) { + void updateWithBlock(List blocks, UnmodifiableListView fields) { + _fields = fields; _rows = blocks.expand((block) => block.rowOrders).map((rowOrder) { return RowData.fromBlockRow(gridId, rowOrder, _fields); }).toList(); } - void updateFields(List fields) { + void updateFields(UnmodifiableListView fields) { if (fields.isEmpty) { return; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 7df38179ac..1308e1a67e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -2,7 +2,6 @@ export 'grid_bloc.dart'; export 'row/row_bloc.dart'; export 'row/row_service.dart'; export 'grid_service.dart'; -export 'data.dart'; export 'grid_header_bloc.dart'; // Field diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index ec9b8ff04d..d6bc43e50e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -80,9 +80,9 @@ class RowBloc extends Bloc { ); }); - _fieldCache.addListener((fields) { + _fieldCache.listenOnFieldChanged((fields) { if (!isClosed) { - add(RowEvent.didReceiveFieldUpdate(fields)); + // add(RowEvent.didReceiveFieldUpdate(fields)); } }); 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 cb1cb1c888..5a772693c7 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 @@ -77,7 +77,7 @@ class FlowyGrid extends StatelessWidget { final child = _wrapScrollView( state.fields, [ - _GridHeader(gridId: state.gridId, fields: List.from(state.fields)), + _GridHeader(gridId: state.gridId, fields: state.fields), _GridRows(), const _GridFooter(), ], @@ -150,7 +150,8 @@ class _GridHeader extends StatelessWidget { @override Widget build(BuildContext context) { - return GridHeaderSliverAdaptor(gridId: gridId, fields: fields); + final fieldCache = context.read().fieldCache; + return GridHeaderSliverAdaptor(gridId: gridId, fieldCache: fieldCache); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 3893ac7784..15fb64f990 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -14,18 +14,19 @@ import 'field_cell.dart'; class GridHeaderSliverAdaptor extends StatelessWidget { final String gridId; - final List fields; + final GridFieldCache fieldCache; - const GridHeaderSliverAdaptor({required this.gridId, required this.fields, Key? key}) : super(key: key); + const GridHeaderSliverAdaptor({required this.gridId, required this.fieldCache, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: gridId, param2: fields)..add(const GridHeaderEvent.initial()), + create: (context) => + getIt(param1: gridId, param2: fieldCache)..add(const GridHeaderEvent.initial()), child: BlocBuilder( builder: (context, state) { return SliverPersistentHeader( - delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: fields), + delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: state.fields), floating: true, pinned: true, ); @@ -77,6 +78,7 @@ class _GridHeader extends StatelessWidget { return BlocBuilder( builder: (context, state) { final cells = state.fields + .where((field) => field.visibility) .map((field) => GridFieldCellContext(gridId: gridId, field: field)) .map((ctx) => GridFieldCell(ctx, key: ValueKey(ctx.field.id))) .toList(); From ac766c0359387d65a70fbb919db23e8d7292c45b Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 14 Apr 2022 21:16:29 +0800 Subject: [PATCH 153/179] chore: fix row rebuild refresh issue --- .../lib/startup/tasks/app_widget.dart | 12 +++++----- .../application/grid/field/grid_listenr.dart | 2 +- .../application/grid/grid_header_bloc.dart | 8 +++---- .../application/grid/grid_service.dart | 11 +++++++++- .../application/grid/row/row_bloc.dart | 18 +++++++-------- .../plugins/grid/src/grid_page.dart | 22 ++++++++++++++----- .../flowy-grid/dart_notification.pbenum.dart | 4 ++-- .../flowy-grid/dart_notification.pbjson.dart | 4 ++-- .../flowy-grid/src/dart_notification.rs | 2 +- .../src/protobuf/model/dart_notification.rs | 12 +++++----- .../protobuf/proto/dart_notification.proto | 2 +- .../flowy-grid/src/services/grid_editor.rs | 2 +- 12 files changed, 59 insertions(+), 40 deletions(-) diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 3dba94ce0a..1747cfd8ec 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -113,7 +113,7 @@ class ApplicationBlocObserver extends BlocObserver { // ignore: unnecessary_overrides void onTransition(Bloc bloc, Transition transition) { // Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}"); - Log.debug("${transition.nextState}"); + // Log.debug("${transition.nextState}"); super.onTransition(bloc, transition); } @@ -123,9 +123,9 @@ class ApplicationBlocObserver extends BlocObserver { super.onError(bloc, error, stackTrace); } - @override - void onEvent(Bloc bloc, Object? event) { - // Log.debug("$event"); - super.onEvent(bloc, event); - } + // @override + // void onEvent(Bloc bloc, Object? event) { + // Log.debug("$event"); + // super.onEvent(bloc, event); + // } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index d823207f83..c257fe3c0d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -24,7 +24,7 @@ class GridFieldsListener { void _handler(GridNotification ty, Either result) { switch (ty) { - case GridNotification.DidUpdateGrid: + case GridNotification.DidUpdateGridField: result.fold( (payload) => updateFieldsNotifier.value = left(GridFieldChangeset.fromBuffer(payload)), (error) => updateFieldsNotifier.value = right(error), diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart index c7ce6c21f1..13f65ff4d6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -2,20 +2,18 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'field/field_service.dart'; import 'grid_service.dart'; part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc { - final FieldService _fieldService; + // final FieldService _fieldService; final GridFieldCache fieldCache; GridHeaderBloc({ required String gridId, required this.fieldCache, - }) : _fieldService = FieldService(gridId: gridId), - super(GridHeaderState.initial(fieldCache.clonedFields)) { + }) : super(GridHeaderState.initial(fieldCache.clonedFields)) { on( (event, emit) async { await event.map( @@ -31,7 +29,7 @@ class GridHeaderBloc extends Bloc { } Future _startListening() async { - fieldCache.listenOnFieldChanged((fields) { + fieldCache.addListener(() {}, onChanged: (fields) { if (!isClosed) { add(GridHeaderEvent.didReceiveFieldUpdate(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 fc853ef8b7..b79c2e5e59 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -74,6 +74,15 @@ class GridFieldCache { _fieldNotifier.addListener(() => onFieldChanged(clonedFields)); } + void addListener(VoidCallback listener, {void Function(List)? onChanged}) { + _fieldNotifier.addListener(() { + if (onChanged != null) { + onChanged(clonedFields); + } + listener(); + }); + } + void _removeFields(List deletedFields) { if (deletedFields.isEmpty) { return; @@ -130,7 +139,7 @@ class GridRowCache { GridRowCache({required this.gridId}); - List get rows => _rows; + List get rows => [..._rows]; void updateWithBlock(List blocks, UnmodifiableListView fields) { _fields = fields; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index d6bc43e50e..dbbe9b054d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -34,12 +34,12 @@ class RowBloc extends Bloc { createRow: (_CreateRow value) { _rowService.createRow(); }, - didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) async { - await _handleFieldUpdate(emit, value); - }, didUpdateRow: (_DidUpdateRow value) async { _handleRowUpdate(value, emit); }, + fieldsDidUpdate: (_FieldsDidUpdate value) async { + await _handleFieldUpdate(emit); + }, ); }, ); @@ -53,15 +53,15 @@ class RowBloc extends Bloc { )); } - Future _handleFieldUpdate(Emitter emit, _DidReceiveFieldUpdate value) async { + Future _handleFieldUpdate(Emitter emit) async { final optionRow = await state.row; final CellDataMap cellDataMap = optionRow.fold( () => CellDataMap.identity(), - (row) => _makeCellDatas(row, value.fields), + (row) => _makeCellDatas(row, _fieldCache.unmodifiableFields), ); emit(state.copyWith( - rowData: state.rowData.copyWith(fields: value.fields), + rowData: state.rowData.copyWith(fields: _fieldCache.unmodifiableFields), cellDataMap: Some(cellDataMap), )); } @@ -80,9 +80,9 @@ class RowBloc extends Bloc { ); }); - _fieldCache.listenOnFieldChanged((fields) { + _fieldCache.addListener(() { if (!isClosed) { - // add(RowEvent.didReceiveFieldUpdate(fields)); + add(const RowEvent.fieldsDidUpdate()); } }); @@ -118,7 +118,7 @@ class RowBloc extends Bloc { class RowEvent with _$RowEvent { const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; - const factory RowEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; + const factory RowEvent.fieldsDidUpdate() = _FieldsDidUpdate; const factory RowEvent.didUpdateRow(Row row) = _DidUpdateRow; } 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 5a772693c7..a3f8a3e064 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 @@ -40,7 +40,7 @@ class _GridPageState extends State { return state.loadingState.map( loading: (_) => const Center(child: CircularProgressIndicator.adaptive()), finish: (result) => result.successOrFail.fold( - (_) => FlowyGrid(), + (_) => const FlowyGrid(), (err) => FlowyErrorPage(err.toString()), ), ); @@ -65,9 +65,15 @@ class _GridPageState extends State { } } -class FlowyGrid extends StatelessWidget { +class FlowyGrid extends StatefulWidget { + const FlowyGrid({Key? key}) : super(key: key); + + @override + State createState() => _FlowyGridState(); +} + +class _FlowyGridState extends State { final _scrollController = GridScrollController(); - FlowyGrid({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -155,9 +161,15 @@ class _GridHeader extends StatelessWidget { } } -class _GridRows extends StatelessWidget { +class _GridRows extends StatefulWidget { + const _GridRows({Key? key}) : super(key: key); + + @override + State<_GridRows> createState() => _GridRowsState(); +} + +class _GridRowsState extends State<_GridRows> { final _key = GlobalKey(); - _GridRows({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index d39002e540..7b43def65e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -15,7 +15,7 @@ class GridNotification extends $pb.ProtobufEnum { static const GridNotification DidUpdateGridBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridBlock'); static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); static const GridNotification DidUpdateCell = GridNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateCell'); - static const GridNotification DidUpdateGrid = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGrid'); + static const GridNotification DidUpdateGridField = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridField'); static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); static const $core.List values = [ @@ -24,7 +24,7 @@ class GridNotification extends $pb.ProtobufEnum { DidUpdateGridBlock, DidUpdateRow, DidUpdateCell, - DidUpdateGrid, + DidUpdateGridField, DidUpdateField, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 787a77ffa1..8c262092db 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -17,10 +17,10 @@ const GridNotification$json = const { const {'1': 'DidUpdateGridBlock', '2': 20}, const {'1': 'DidUpdateRow', '2': 30}, const {'1': 'DidUpdateCell', '2': 31}, - const {'1': 'DidUpdateGrid', '2': 40}, + const {'1': 'DidUpdateGridField', '2': 40}, const {'1': 'DidUpdateField', '2': 41}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhYKEkRpZFVwZGF0ZUdyaWRCbG9jaxAUEhAKDERpZFVwZGF0ZVJvdxAeEhEKDURpZFVwZGF0ZUNlbGwQHxIRCg1EaWRVcGRhdGVHcmlkECgSEgoORGlkVXBkYXRlRmllbGQQKQ=='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhYKEkRpZFVwZGF0ZUdyaWRCbG9jaxAUEhAKDERpZFVwZGF0ZVJvdxAeEhEKDURpZFVwZGF0ZUNlbGwQHxIWChJEaWRVcGRhdGVHcmlkRmllbGQQKBISCg5EaWRVcGRhdGVGaWVsZBAp'); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index a2a1de0a9f..156ba9058a 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -9,7 +9,7 @@ pub enum GridNotification { DidUpdateGridBlock = 20, DidUpdateRow = 30, DidUpdateCell = 31, - DidUpdateGrid = 40, + DidUpdateGridField = 40, DidUpdateField = 41, } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 326ae3ef4e..338737c643 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -30,7 +30,7 @@ pub enum GridNotification { DidUpdateGridBlock = 20, DidUpdateRow = 30, DidUpdateCell = 31, - DidUpdateGrid = 40, + DidUpdateGridField = 40, DidUpdateField = 41, } @@ -46,7 +46,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { 20 => ::std::option::Option::Some(GridNotification::DidUpdateGridBlock), 30 => ::std::option::Option::Some(GridNotification::DidUpdateRow), 31 => ::std::option::Option::Some(GridNotification::DidUpdateCell), - 40 => ::std::option::Option::Some(GridNotification::DidUpdateGrid), + 40 => ::std::option::Option::Some(GridNotification::DidUpdateGridField), 41 => ::std::option::Option::Some(GridNotification::DidUpdateField), _ => ::std::option::Option::None } @@ -59,7 +59,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { GridNotification::DidUpdateGridBlock, GridNotification::DidUpdateRow, GridNotification::DidUpdateCell, - GridNotification::DidUpdateGrid, + GridNotification::DidUpdateGridField, GridNotification::DidUpdateField, ]; values @@ -89,11 +89,11 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x97\x01\n\x10GridNotification\x12\x0b\n\ + \n\x17dart_notification.proto*\x9c\x01\n\x10GridNotification\x12\x0b\n\ \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x16\n\x12DidUp\ dateGridBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUp\ - dateCell\x10\x1f\x12\x11\n\rDidUpdateGrid\x10(\x12\x12\n\x0eDidUpdateFie\ - ld\x10)b\x06proto3\ + dateCell\x10\x1f\x12\x16\n\x12DidUpdateGridField\x10(\x12\x12\n\x0eDidUp\ + dateField\x10)b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 20cf529f3e..a4e5188346 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -6,6 +6,6 @@ enum GridNotification { DidUpdateGridBlock = 20; DidUpdateRow = 30; DidUpdateCell = 31; - DidUpdateGrid = 40; + DidUpdateGridField = 40; DidUpdateField = 41; } 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 5cd4ebca87..357c38ba0e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -473,7 +473,7 @@ impl ClientGridEditor { } async fn notify_did_update_grid(&self, changeset: GridFieldChangeset) -> FlowyResult<()> { - send_dart_notification(&self.grid_id, GridNotification::DidUpdateGrid) + send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridField) .payload(changeset) .send(); Ok(()) From b282a14b58aa7a0e19aad5b9ff5386f6c7754c41 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 14 Apr 2022 21:57:00 +0800 Subject: [PATCH 154/179] chore: add sync feature --- frontend/rust-lib/dart-ffi/Cargo.toml | 2 +- frontend/rust-lib/flowy-folder/Cargo.toml | 3 +- .../src/services/folder_editor.rs | 43 ++++++++++++------- .../flowy-folder/src/services/web_socket.rs | 1 + .../field/type_options/date_type_option.rs | 2 +- .../flowy-grid/src/services/grid_editor.rs | 2 +- frontend/rust-lib/flowy-sdk/Cargo.toml | 3 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 2 +- frontend/rust-lib/flowy-text-block/Cargo.toml | 3 +- .../rust-lib/flowy-text-block/src/editor.rs | 25 ++++++++--- .../flowy-text-block/src/web_socket.rs | 3 ++ frontend/rust-lib/flowy-user/Cargo.toml | 1 - .../src/client_grid/grid_meta_pad.rs | 6 +-- 13 files changed, 62 insertions(+), 34 deletions(-) diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index df26694331..bbc3c3f35b 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -31,7 +31,7 @@ flowy-derive = {path = "../../../shared-lib/flowy-derive" } [features] default = ["flowy-sdk/dart", "dart-notify/dart", "flutter"] flutter = [] -http_server = ["flowy-sdk/http_server", "flowy-sdk/use_bunyan"] +http_sync = ["flowy-sdk/http_sync", "flowy-sdk/use_bunyan"] #use_serde = ["bincode"] #use_protobuf= ["protobuf"] diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 9605212726..ddc6f1f586 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -44,6 +44,7 @@ lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file [features] default = [] -http_server = [] +sync = [] +cloud_sync = ["sync"] flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-revision/flowy_unit_test"] dart = ["lib-infra/dart"] \ No newline at end of file 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 b7c30919b6..6ea1a7e2ec 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -1,4 +1,3 @@ -use crate::services::web_socket::make_folder_ws_manager; use flowy_sync::{ client_folder::{FolderChange, FolderPad}, entities::{revision::Revision, ws_data::ServerRevisionWSData}, @@ -11,7 +10,6 @@ use flowy_sync::util::make_delta_from_revisions; use flowy_revision::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, - RevisionWebSocketManager, }; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; @@ -21,13 +19,16 @@ use std::sync::Arc; pub struct ClientFolderEditor { user_id: String, + #[allow(dead_code)] pub(crate) folder_id: FolderId, pub(crate) folder: Arc>, rev_manager: Arc, - // ws_manager: Arc, + #[cfg(feature = "sync")] + ws_manager: Arc, } impl ClientFolderEditor { + #[allow(unused_variables)] pub async fn new( user_id: &str, folder_id: &FolderId, @@ -40,14 +41,16 @@ impl ClientFolderEditor { }); let folder = Arc::new(RwLock::new(rev_manager.load::(Some(cloud)).await?)); let rev_manager = Arc::new(rev_manager); - // let ws_manager = make_folder_ws_manager( - // user_id, - // folder_id.as_ref(), - // rev_manager.clone(), - // web_socket, - // folder.clone(), - // ) - // .await; + + #[cfg(feature = "sync")] + let ws_manager = crate::services::web_socket::make_folder_ws_manager( + user_id, + folder_id.as_ref(), + rev_manager.clone(), + web_socket, + folder.clone(), + ) + .await; let user_id = user_id.to_owned(); let folder_id = folder_id.to_owned(); @@ -56,15 +59,23 @@ impl ClientFolderEditor { folder_id, folder, rev_manager, - // ws_manager, + #[cfg(feature = "sync")] + ws_manager, }) } + #[cfg(feature = "sync")] pub async fn receive_ws_data(&self, data: ServerRevisionWSData) -> FlowyResult<()> { - // let _ = self.ws_manager.ws_passthrough_tx.send(data).await.map_err(|e| { - // let err_msg = format!("{} passthrough error: {}", self.folder_id, e); - // FlowyError::internal().context(err_msg) - // })?; + let _ = self.ws_manager.ws_passthrough_tx.send(data).await.map_err(|e| { + let err_msg = format!("{} passthrough error: {}", self.folder_id, e); + FlowyError::internal().context(err_msg) + })?; + + Ok(()) + } + + #[cfg(not(feature = "sync"))] + pub async fn receive_ws_data(&self, _data: ServerRevisionWSData) -> FlowyResult<()> { Ok(()) } 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 c14db04d3f..75db905d63 100644 --- a/frontend/rust-lib/flowy-folder/src/services/web_socket.rs +++ b/frontend/rust-lib/flowy-folder/src/services/web_socket.rs @@ -14,6 +14,7 @@ use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta}; use parking_lot::RwLock; use std::{sync::Arc, time::Duration}; +#[allow(dead_code)] pub(crate) async fn make_folder_ws_manager( user_id: &str, folder_id: &str, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index c4ef4614f1..81e77f2645 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -47,7 +47,7 @@ impl DateTypeOption { if self.include_time { format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) } else { - format!("{}", self.date_format.format_str()) + self.date_format.format_str().to_string() } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 357c38ba0e..41a70d8549 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -153,7 +153,7 @@ impl ClientGridEditor { .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) .await?; - let _ = self.notify_grid_did_update_field(&field_id).await?; + let _ = self.notify_grid_did_update_field(field_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 9ac3bef2f6..2ffb444962 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -38,6 +38,7 @@ tokio = { version = "1", features = ["full"]} futures-util = "0.3.15" [features] -http_server = ["flowy-user/http_server", "flowy-folder/http_server", "flowy-text-block/http_server"] +http_sync = ["flowy-folder/cloud_sync", "flowy-text-block/cloud_sync"] +native_sync = ["flowy-folder/cloud_sync", "flowy-text-block/cloud_sync"] use_bunyan = ["lib-log/use_bunyan"] dart = ["flowy-user/dart", "flowy-net/dart", "flowy-folder/dart", "flowy-sync/dart", "flowy-grid/dart", "flowy-text-block/dart"] diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 06a140805e..b426b40550 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -193,7 +193,7 @@ fn mk_local_server( server_config: &ClientServerConfiguration, ) -> (Option>, Arc) { let ws_addr = server_config.ws_addr(); - if cfg!(feature = "http_server") { + if cfg!(feature = "http_sync") { let ws_conn = Arc::new(FlowyWebSocketConnect::new(ws_addr)); (None, ws_conn) } else { diff --git a/frontend/rust-lib/flowy-text-block/Cargo.toml b/frontend/rust-lib/flowy-text-block/Cargo.toml index 84c0cf9605..d9180a97bf 100644 --- a/frontend/rust-lib/flowy-text-block/Cargo.toml +++ b/frontend/rust-lib/flowy-text-block/Cargo.toml @@ -51,6 +51,7 @@ rand = "0.7.3" lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } [features] -http_server = [] +sync = [] +cloud_sync = ["sync"] flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-revision/flowy_unit_test"] dart = ["lib-infra/dart"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-text-block/src/editor.rs b/frontend/rust-lib/flowy-text-block/src/editor.rs index 215c3d079d..55160010bf 100644 --- a/frontend/rust-lib/flowy-text-block/src/editor.rs +++ b/frontend/rust-lib/flowy-text-block/src/editor.rs @@ -1,4 +1,4 @@ -use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; +use crate::web_socket::EditorCommandSender; use crate::{ errors::FlowyError, queue::{EditBlockQueue, EditorCommand}, @@ -6,9 +6,7 @@ use crate::{ }; use bytes::Bytes; use flowy_error::{internal_error, FlowyResult}; -use flowy_revision::{ - RevisionCloudService, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, RevisionWebSocketManager, -}; +use flowy_revision::{RevisionCloudService, RevisionManager, RevisionObjectBuilder, RevisionWebSocket}; use flowy_sync::entities::ws_data::ServerRevisionWSData; use flowy_sync::{ entities::{revision::Revision, text_block_info::TextBlockInfo}, @@ -27,6 +25,7 @@ pub struct ClientTextBlockEditor { pub doc_id: String, #[allow(dead_code)] rev_manager: Arc, + #[cfg(feature = "sync")] ws_manager: Arc, edit_cmd_tx: EditorCommandSender, } @@ -36,16 +35,17 @@ impl ClientTextBlockEditor { doc_id: &str, user: Arc, mut rev_manager: RevisionManager, - rev_web_socket: Arc, + _rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { let document_info = rev_manager.load::(Some(cloud_service)).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); - let user_id = user.user_id()?; + let _user_id = user.user_id()?; let edit_cmd_tx = spawn_edit_queue(user, rev_manager.clone(), delta); + #[cfg(feature = "sync")] let ws_manager = make_block_ws_manager( doc_id.clone(), user_id.clone(), @@ -57,6 +57,7 @@ impl ClientTextBlockEditor { let editor = Arc::new(Self { doc_id, rev_manager, + #[cfg(feature = "sync")] ws_manager, edit_cmd_tx, }); @@ -158,17 +159,29 @@ impl ClientTextBlockEditor { Ok(()) } + #[cfg(feature = "sync")] pub fn stop(&self) { self.ws_manager.stop(); } + #[cfg(not(feature = "sync"))] + pub fn stop(&self) {} + + #[cfg(feature = "sync")] pub(crate) async fn receive_ws_data(&self, data: ServerRevisionWSData) -> Result<(), FlowyError> { self.ws_manager.receive_ws_data(data).await } + #[cfg(not(feature = "sync"))] + pub(crate) async fn receive_ws_data(&self, _data: ServerRevisionWSData) -> Result<(), FlowyError> { + Ok(()) + } + #[cfg(feature = "sync")] pub(crate) fn receive_ws_state(&self, state: &WSConnectState) { self.ws_manager.connect_state_changed(state.clone()); } + #[cfg(not(feature = "sync"))] + pub(crate) fn receive_ws_state(&self, _state: &WSConnectState) {} } impl std::ops::Drop for ClientTextBlockEditor { diff --git a/frontend/rust-lib/flowy-text-block/src/web_socket.rs b/frontend/rust-lib/flowy-text-block/src/web_socket.rs index 8854acfd9f..a44214f4f2 100644 --- a/frontend/rust-lib/flowy-text-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-text-block/src/web_socket.rs @@ -23,6 +23,7 @@ use tokio::sync::{ pub(crate) type EditorCommandSender = Sender; pub(crate) type EditorCommandReceiver = Receiver; +#[allow(dead_code)] pub(crate) async fn make_block_ws_manager( doc_id: String, user_id: String, @@ -49,6 +50,7 @@ pub(crate) async fn make_block_ws_manager( ws_manager } +#[allow(dead_code)] fn listen_document_ws_state(_user_id: &str, _doc_id: &str, mut subscriber: broadcast::Receiver) { tokio::spawn(async move { while let Ok(state) = subscriber.recv().await { @@ -67,6 +69,7 @@ pub(crate) struct TextBlockRevisionWSDataStream { } impl TextBlockRevisionWSDataStream { + #[allow(dead_code)] pub fn new(conflict_controller: RichTextConflictController) -> Self { Self { conflict_controller: Arc::new(conflict_controller), diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index d6f52e6d73..96e6141ed6 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -37,7 +37,6 @@ futures = "0.3.15" nanoid = "0.4.0" [features] -http_server = [] dart = ["lib-infra/dart"] [build-dependencies] diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index ebc5483b5b..5c59437d4f 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -3,13 +3,11 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ - gen_field_id, gen_grid_id, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, - GridBlockMetaChangeset, GridMeta, IndexField, + gen_grid_id, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, + GridMeta, }; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; - -use futures::StreamExt; use std::sync::Arc; pub type GridMetaDelta = PlainTextDelta; From a81db92ee1738274e919d9c7836f5cb105f41a34 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 14 Apr 2022 21:57:51 +0800 Subject: [PATCH 155/179] chore: fix warnings --- .../lib/workspace/presentation/plugins/grid/src/grid_page.dart | 2 +- .../plugins/grid/src/widgets/footer/grid_footer.dart | 1 - .../plugins/grid/src/widgets/header/field_cell.dart | 1 - .../plugins/grid/src/widgets/toolbar/grid_property.dart | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) 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 a3f8a3e064..790dc0f83c 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 @@ -84,7 +84,7 @@ class _FlowyGridState extends State { state.fields, [ _GridHeader(gridId: state.gridId, fields: state.fields), - _GridRows(), + const _GridRows(), const _GridFooter(), ], ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index a99e87f5fa..6ed8700cfc 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -1,5 +1,4 @@ import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index 83fcade362..e9fa11d883 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -6,7 +6,6 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_type_extension.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index 0a9cddedd5..54e2d5e97a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -10,7 +10,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; From 676dffbf2131809808ec4979e195b1ee86cae1c9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 15 Apr 2022 10:24:59 +0800 Subject: [PATCH 156/179] chore: reorder fields --- .../grid/setting/property_bloc.dart | 9 +++++-- .../grid/src/widgets/header/grid_header.dart | 27 ++++++++++++------- .../src/widgets/toolbar/grid_property.dart | 14 ++++++---- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index 140aa388cd..0ec31d08b6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -11,10 +12,12 @@ part 'property_bloc.freezed.dart'; class GridPropertyBloc extends Bloc { final FieldService _service; final GridFieldsListener _fieldListener; + final GridFieldCache _fieldCache; GridPropertyBloc({required String gridId, required List fields}) : _service = FieldService(gridId: gridId), _fieldListener = GridFieldsListener(gridId: gridId), + _fieldCache = GridFieldCache(), super(GridPropertyState.initial(gridId, fields)) { on( (event, emit) async { @@ -43,14 +46,16 @@ class GridPropertyBloc extends Bloc { @override Future close() async { await _fieldListener.stop(); + _fieldCache.dispose(); return super.close(); } void _startListening() { _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( - (fields) { - // add(GridPropertyEvent.didReceiveFieldUpdate(fields)); + (changeset) { + _fieldCache.applyChangeset(changeset); + add(GridPropertyEvent.didReceiveFieldUpdate(_fieldCache.clonedFields)); }, (err) => Log.error(err), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 15fb64f990..dcf5702f40 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -5,10 +5,11 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - +import 'package:reorderables/reorderables.dart'; import 'field_editor.dart'; import 'field_cell.dart'; @@ -62,7 +63,7 @@ class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate } } -class _GridHeader extends StatelessWidget { +class _GridHeader extends StatefulWidget { final String gridId; final List fields; @@ -72,26 +73,34 @@ class _GridHeader extends StatelessWidget { required this.fields, }) : super(key: key); + @override + State<_GridHeader> createState() => _GridHeaderState(); +} + +class _GridHeaderState extends State<_GridHeader> { @override Widget build(BuildContext context) { final theme = context.watch(); return BlocBuilder( + buildWhen: (previous, current) => previous.fields != current.fields, builder: (context, state) { final cells = state.fields .where((field) => field.visibility) - .map((field) => GridFieldCellContext(gridId: gridId, field: field)) + .map((field) => GridFieldCellContext(gridId: widget.gridId, field: field)) .map((ctx) => GridFieldCell(ctx, key: ValueKey(ctx.field.id))) .toList(); return Container( color: theme.surface, - child: Row( + child: ReorderableRow( crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _CellLeading(), - ...cells, - _CellTrailing(gridId: gridId), - ], + scrollController: ScrollController(), + header: const _CellLeading(), + footer: _CellTrailing(gridId: widget.gridId), + onReorder: (int oldIndex, int newIndex) { + Log.info("from $oldIndex to $newIndex"); + }, + children: cells, ), ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index 54e2d5e97a..75898d5ba7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -10,6 +10,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -45,16 +46,19 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { getIt(param1: gridId, param2: fields)..add(const GridPropertyEvent.initial()), child: BlocBuilder( builder: (context, state) { - final children = state.fields.map((field) { + final cells = state.fields.map((field) { return _GridPropertyCell(gridId: gridId, field: field, key: ValueKey(field.id)); }).toList(); - return ReorderableListView( + return ListView.separated( shrinkWrap: true, - onReorder: (int oldIndex, int newIndex) { - context.read().add(GridPropertyEvent.moveField(oldIndex, newIndex)); + itemCount: cells.length, + itemBuilder: (BuildContext context, int index) { + return cells[index]; + }, + separatorBuilder: (BuildContext context, int index) { + return VSpace(GridSize.typeOptionSeparatorHeight); }, - children: children, ); }, ), From d71e0de8c32673071847eb9a804cc8313a94b4cf Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 15 Apr 2022 14:21:32 +0800 Subject: [PATCH 157/179] chore: set notifier to null after dispose --- .../application/grid/cell_bloc/cell_listener.dart | 9 +++++---- .../application/grid/cell_bloc/checkbox_cell_bloc.dart | 2 +- .../application/grid/cell_bloc/date_cell_bloc.dart | 4 ++-- .../application/grid/cell_bloc/number_cell_bloc.dart | 4 ++-- .../application/grid/cell_bloc/selection_cell_bloc.dart | 4 ++-- .../grid/cell_bloc/selection_editor_bloc.dart | 4 ++-- .../application/grid/field/field_cell_bloc.dart | 2 +- .../workspace/application/grid/field/field_listener.dart | 9 +++++---- .../workspace/application/grid/field/grid_listenr.dart | 9 +++++---- .../lib/workspace/application/grid/grid_bloc.dart | 2 +- .../lib/workspace/application/grid/row/row_bloc.dart | 2 +- .../lib/workspace/application/grid/row/row_listener.dart | 9 +++++---- .../application/grid/setting/property_bloc.dart | 2 +- .../plugins/grid/src/widgets/header/grid_header.dart | 3 ++- 14 files changed, 35 insertions(+), 30 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart index d1fb0acc0c..314345017e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart @@ -12,7 +12,7 @@ typedef UpdateFieldNotifiedValue = Either; class CellListener { final String rowId; final String fieldId; - PublishNotifier updateCellNotifier = PublishNotifier(); + PublishNotifier? updateCellNotifier = PublishNotifier(); GridNotificationListener? _listener; CellListener({required this.rowId, required this.fieldId}); @@ -24,8 +24,8 @@ class CellListener { switch (ty) { case GridNotification.DidUpdateCell: result.fold( - (payload) => updateCellNotifier.value = left(CellNotificationData.fromBuffer(payload)), - (error) => updateCellNotifier.value = right(error), + (payload) => updateCellNotifier?.value = left(CellNotificationData.fromBuffer(payload)), + (error) => updateCellNotifier?.value = right(error), ); break; default: @@ -35,6 +35,7 @@ class CellListener { Future stop() async { await _listener?.stop(); - updateCellNotifier.dispose(); + updateCellNotifier?.dispose(); + updateCellNotifier = null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 0f56b9c53c..2d937b8cd2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -43,7 +43,7 @@ class CheckboxCellBloc extends Bloc { } void _startListening() { - _listener.updateCellNotifier.addPublishListener((result) { + _listener.updateCellNotifier?.addPublishListener((result) { result.fold( (notificationData) async => await _loadCellData(), (err) => Log.error(err), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index 7dd58bf5ac..b4b6d7e152 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -52,7 +52,7 @@ class DateCellBloc extends Bloc { } void _startListening() { - _cellListener.updateCellNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier?.addPublishListener((result) { result.fold( (notificationData) => _loadCellData(), (err) => Log.error(err), @@ -60,7 +60,7 @@ class DateCellBloc extends Bloc { }); _cellListener.start(); - _fieldListener.updateFieldNotifier.addPublishListener((result) { + _fieldListener.updateFieldNotifier?.addPublishListener((result) { result.fold( (field) { if (!isClosed) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index a145305bbe..287d70b701 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -59,7 +59,7 @@ class NumberCellBloc extends Bloc { } void _startListening() { - _cellListener.updateCellNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier?.addPublishListener((result) { result.fold( (notificationData) async { await _getCellData(); @@ -69,7 +69,7 @@ class NumberCellBloc extends Bloc { }); _cellListener.start(); - _fieldListener.updateFieldNotifier.addPublishListener((result) { + _fieldListener.updateFieldNotifier?.addPublishListener((result) { result.fold( (field) => _getCellData(), (err) => Log.error(err), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index b7e472e181..dbca1b5ae3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -64,7 +64,7 @@ class SelectionCellBloc extends Bloc { } void _startListening() { - _cellListener.updateCellNotifier.addPublishListener((result) { + _cellListener.updateCellNotifier?.addPublishListener((result) { result.fold( (notificationData) => _loadOptions(), (err) => Log.error(err), @@ -72,7 +72,7 @@ class SelectionCellBloc extends Bloc { }); _cellListener.start(); - _fieldListener.updateFieldNotifier.addPublishListener((result) { + _fieldListener.updateFieldNotifier?.addPublishListener((result) { result.fold( (field) => _loadOptions(), (err) => Log.error(err), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 5d2c52dc0e..813b779646 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -134,7 +134,7 @@ class SelectOptionEditorBloc extends Bloc _loadOptions(), (err) => Log.error(err), @@ -142,7 +142,7 @@ class SelectOptionEditorBloc extends Bloc { } void _startListening() { - _fieldListener.updateFieldNotifier.addPublishListener((result) { + _fieldListener.updateFieldNotifier?.addPublishListener((result) { result.fold( (field) { if (!isClosed) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart index 450d88fe18..b31a9c3ff5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart @@ -11,7 +11,7 @@ typedef UpdateFieldNotifiedValue = Either; class SingleFieldListener { final String fieldId; - PublishNotifier updateFieldNotifier = PublishNotifier(); + PublishNotifier? updateFieldNotifier = PublishNotifier(); GridNotificationListener? _listener; SingleFieldListener({required this.fieldId}); @@ -30,8 +30,8 @@ class SingleFieldListener { switch (ty) { case GridNotification.DidUpdateField: result.fold( - (payload) => updateFieldNotifier.value = left(Field.fromBuffer(payload)), - (error) => updateFieldNotifier.value = right(error), + (payload) => updateFieldNotifier?.value = left(Field.fromBuffer(payload)), + (error) => updateFieldNotifier?.value = right(error), ); break; default: @@ -41,6 +41,7 @@ class SingleFieldListener { Future stop() async { await _listener?.stop(); - updateFieldNotifier.dispose(); + updateFieldNotifier?.dispose(); + updateFieldNotifier = null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index c257fe3c0d..6774205a5e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -11,7 +11,7 @@ typedef UpdateFieldNotifiedValue = Either; class GridFieldsListener { final String gridId; - PublishNotifier updateFieldsNotifier = PublishNotifier(); + PublishNotifier? updateFieldsNotifier = PublishNotifier(); GridNotificationListener? _listener; GridFieldsListener({required this.gridId}); @@ -26,8 +26,8 @@ class GridFieldsListener { switch (ty) { case GridNotification.DidUpdateGridField: result.fold( - (payload) => updateFieldsNotifier.value = left(GridFieldChangeset.fromBuffer(payload)), - (error) => updateFieldsNotifier.value = right(error), + (payload) => updateFieldsNotifier?.value = left(GridFieldChangeset.fromBuffer(payload)), + (error) => updateFieldsNotifier?.value = right(error), ); break; default: @@ -37,6 +37,7 @@ class GridFieldsListener { Future stop() async { await _listener?.stop(); - updateFieldsNotifier.dispose(); + updateFieldsNotifier?.dispose(); + updateFieldsNotifier = null; } } 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 882b3eb5b4..c37c31ec46 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -58,7 +58,7 @@ class GridBloc extends Bloc { } void _startListening() { - _fieldListener.updateFieldsNotifier.addPublishListener((result) { + _fieldListener.updateFieldsNotifier?.addPublishListener((result) { result.fold( (changeset) { fieldCache.applyChangeset(changeset); diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index dbbe9b054d..b16d75dc92 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -73,7 +73,7 @@ class RowBloc extends Bloc { } Future _startListening() async { - _rowlistener.updateRowNotifier.addPublishListener((result) { + _rowlistener.updateRowNotifier?.addPublishListener((result) { result.fold( (row) => add(RowEvent.didUpdateRow(row)), (err) => Log.error(err), diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart index 716d252802..7d947b8482 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart @@ -12,7 +12,7 @@ typedef UpdateFieldNotifiedValue = Either, FlowyError>; class RowListener { final String rowId; - PublishNotifier updateRowNotifier = PublishNotifier(); + PublishNotifier? updateRowNotifier = PublishNotifier(); GridNotificationListener? _listener; RowListener({required this.rowId}); @@ -25,8 +25,8 @@ class RowListener { switch (ty) { case GridNotification.DidUpdateRow: result.fold( - (payload) => updateRowNotifier.value = left(Row.fromBuffer(payload)), - (error) => updateRowNotifier.value = right(error), + (payload) => updateRowNotifier?.value = left(Row.fromBuffer(payload)), + (error) => updateRowNotifier?.value = right(error), ); break; default: @@ -36,6 +36,7 @@ class RowListener { Future stop() async { await _listener?.stop(); - updateRowNotifier.dispose(); + updateRowNotifier?.dispose(); + updateRowNotifier = null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index 0ec31d08b6..634bb1e56d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -51,7 +51,7 @@ class GridPropertyBloc extends Bloc { } void _startListening() { - _fieldListener.updateFieldsNotifier.addPublishListener((result) { + _fieldListener.updateFieldsNotifier?.addPublishListener((result) { result.fold( (changeset) { _fieldCache.applyChangeset(changeset); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index dcf5702f40..a00b9e6295 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -25,6 +25,7 @@ class GridHeaderSliverAdaptor extends StatelessWidget { create: (context) => getIt(param1: gridId, param2: fieldCache)..add(const GridHeaderEvent.initial()), child: BlocBuilder( + buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { return SliverPersistentHeader( delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: state.fields), @@ -45,7 +46,7 @@ class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return _GridHeader(gridId: gridId, fields: fields, key: ObjectKey(fields)); + return _GridHeader(gridId: gridId, fields: fields); } @override From 6dbb70899129fc7578bf9996d917a1d8c890cf8e Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 15 Apr 2022 15:41:55 +0800 Subject: [PATCH 158/179] chore: repalce sliver header with single scroll view --- .../application/grid/grid_header_bloc.dart | 8 ++- .../grid/src/controller/grid_scroll.dart | 27 +++++---- .../plugins/grid/src/grid_page.dart | 43 +++++++------ .../grid/src/widgets/header/grid_header.dart | 60 +++++++++++-------- frontend/app_flowy/pubspec.lock | 7 +++ frontend/app_flowy/pubspec.yaml | 1 + 6 files changed, 93 insertions(+), 53 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart index 13f65ff4d6..8ea390d7ab 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -7,13 +8,14 @@ import 'grid_service.dart'; part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc { - // final FieldService _fieldService; + final FieldService _fieldService; final GridFieldCache fieldCache; GridHeaderBloc({ required String gridId, required this.fieldCache, - }) : super(GridHeaderState.initial(fieldCache.clonedFields)) { + }) : _fieldService = FieldService(gridId: gridId), + super(GridHeaderState.initial(fieldCache.clonedFields)) { on( (event, emit) async { await event.map( @@ -23,6 +25,7 @@ class GridHeaderBloc extends Bloc { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(fields: value.fields)); }, + moveField: (_MoveField value) {}, ); }, ); @@ -46,6 +49,7 @@ class GridHeaderBloc extends Bloc { class GridHeaderEvent with _$GridHeaderEvent { const factory GridHeaderEvent.initial() = _InitialHeader; const factory GridHeaderEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; + const factory GridHeaderEvent.moveField(int fromIndex, int toIndex) = _MoveField; } @freezed diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart index 213b16cfae..dddd93d175 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart @@ -1,21 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:linked_scroll_controller/linked_scroll_controller.dart'; class GridScrollController { - final ScrollController _verticalController = ScrollController(); - final ScrollController _horizontalController = ScrollController(); + final LinkedScrollControllerGroup _scrollGroupContorller; + final ScrollController verticalController; + final ScrollController horizontalController; - ScrollController get verticalController => _verticalController; - ScrollController get horizontalController => _horizontalController; + final List _linkHorizontalControllers = []; - GridScrollController(); + GridScrollController({required LinkedScrollControllerGroup scrollGroupContorller}) + : _scrollGroupContorller = scrollGroupContorller, + verticalController = ScrollController(), + horizontalController = scrollGroupContorller.addAndGet(); - // final SelectionChangeCallback? onSelectionChanged; - - // final ShouldApplySelection? shouldApplySelection; - - // final ScrollCallback? onScroll; + ScrollController linkHorizontalController() { + final controller = _scrollGroupContorller.addAndGet(); + _linkHorizontalControllers.add(controller); + return controller; + } void dispose() { + for (final controller in _linkHorizontalControllers) { + controller.dispose(); + } verticalController.dispose(); horizontalController.dispose(); } 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 790dc0f83c..340f7c7026 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 @@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; +import 'package:linked_scroll_controller/linked_scroll_controller.dart'; import 'controller/grid_scroll.dart'; import 'layout/layout.dart'; import 'layout/sizes.dart'; @@ -73,17 +74,23 @@ class FlowyGrid extends StatefulWidget { } class _FlowyGridState extends State { - final _scrollController = GridScrollController(); + final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup()); + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } @override Widget build(BuildContext context) { return BlocBuilder( buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { + final contentWidth = GridLayout.headerWidth(state.fields); final child = _wrapScrollView( - state.fields, + contentWidth, [ - _GridHeader(gridId: state.gridId, fields: state.fields), const _GridRows(), const _GridFooter(), ], @@ -91,6 +98,7 @@ class _FlowyGridState extends State { return Column(children: [ const _GridToolbarAdaptor(), + _gridHeader(context, state.gridId, contentWidth), Flexible(child: child), ]); }, @@ -98,7 +106,7 @@ class _FlowyGridState extends State { } Widget _wrapScrollView( - List fields, + double contentWidth, List slivers, ) { final verticalScrollView = ScrollConfiguration( @@ -111,7 +119,7 @@ class _FlowyGridState extends State { ); final sizedVerticalScrollView = SizedBox( - width: GridLayout.headerWidth(fields), + width: contentWidth, child: verticalScrollView, ); @@ -128,6 +136,19 @@ class _FlowyGridState extends State { child: horizontalScrollView, ); } + + Widget _gridHeader(BuildContext context, String gridId, double contentWidth) { + final fieldCache = context.read().fieldCache; + + return SizedBox( + width: contentWidth, + child: GridHeaderSliverAdaptor( + gridId: gridId, + fieldCache: fieldCache, + anchorScrollController: _scrollController.linkHorizontalController(), + ), + ); + } } class _GridToolbarAdaptor extends StatelessWidget { @@ -149,18 +170,6 @@ class _GridToolbarAdaptor extends StatelessWidget { } } -class _GridHeader extends StatelessWidget { - final String gridId; - final List fields; - const _GridHeader({Key? key, required this.gridId, required this.fields}) : super(key: key); - - @override - Widget build(BuildContext context) { - final fieldCache = context.read().fieldCache; - return GridHeaderSliverAdaptor(gridId: gridId, fieldCache: fieldCache); - } -} - class _GridRows extends StatefulWidget { const _GridRows({Key? key}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index a00b9e6295..2ac5e5f673 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -13,25 +13,41 @@ import 'package:reorderables/reorderables.dart'; import 'field_editor.dart'; import 'field_cell.dart'; -class GridHeaderSliverAdaptor extends StatelessWidget { +class GridHeaderSliverAdaptor extends StatefulWidget { final String gridId; final GridFieldCache fieldCache; + final ScrollController anchorScrollController; + const GridHeaderSliverAdaptor({ + required this.gridId, + required this.fieldCache, + required this.anchorScrollController, + Key? key, + }) : super(key: key); - const GridHeaderSliverAdaptor({required this.gridId, required this.fieldCache, Key? key}) : super(key: key); + @override + State createState() => _GridHeaderSliverAdaptorState(); +} +class _GridHeaderSliverAdaptorState extends State { @override Widget build(BuildContext context) { return BlocProvider( create: (context) => - getIt(param1: gridId, param2: fieldCache)..add(const GridHeaderEvent.initial()), + getIt(param1: widget.gridId, param2: widget.fieldCache)..add(const GridHeaderEvent.initial()), child: BlocBuilder( buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { - return SliverPersistentHeader( - delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: state.fields), - floating: true, - pinned: true, + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + controller: widget.anchorScrollController, + child: SizedBox(height: GridSize.headerHeight, child: _GridHeader(gridId: widget.gridId)), ); + + // return SliverPersistentHeader( + // delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: state.fields), + // floating: true, + // pinned: true, + // ); }, ), ); @@ -46,7 +62,7 @@ class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return _GridHeader(gridId: gridId, fields: fields); + return _GridHeader(gridId: gridId); } @override @@ -66,13 +82,7 @@ class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate class _GridHeader extends StatefulWidget { final String gridId; - final List fields; - - const _GridHeader({ - Key? key, - required this.gridId, - required this.fields, - }) : super(key: key); + const _GridHeader({Key? key, required this.gridId}) : super(key: key); @override State<_GridHeader> createState() => _GridHeaderState(); @@ -93,15 +103,17 @@ class _GridHeaderState extends State<_GridHeader> { return Container( color: theme.surface, - child: ReorderableRow( - crossAxisAlignment: CrossAxisAlignment.stretch, - scrollController: ScrollController(), - header: const _CellLeading(), - footer: _CellTrailing(gridId: widget.gridId), - onReorder: (int oldIndex, int newIndex) { - Log.info("from $oldIndex to $newIndex"); - }, - children: cells, + child: RepaintBoundary( + child: ReorderableRow( + crossAxisAlignment: CrossAxisAlignment.stretch, + scrollController: ScrollController(), + header: const _CellLeading(), + footer: _CellTrailing(gridId: widget.gridId), + onReorder: (int oldIndex, int newIndex) { + Log.info("from $oldIndex to $newIndex"); + }, + children: cells, + ), ), ); }, diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index 1a3a3172f4..8f7e6d6db2 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -653,6 +653,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.4.0" + linked_scroll_controller: + dependency: "direct main" + description: + name: linked_scroll_controller + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" lint: dependency: transitive description: diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index bcc3303602..fd2b75b9e0 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -75,6 +75,7 @@ dependencies: fluttertoast: ^8.0.8 table_calendar: ^3.0.5 reorderables: + linked_scroll_controller: ^0.2.0 dev_dependencies: flutter_lints: ^1.0.0 From 0c8850503f953910824456d65b15741d0a5af2b5 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 15 Apr 2022 19:56:44 +0800 Subject: [PATCH 159/179] chore: reorder field --- .../application/grid/field/field_service.dart | 11 ++++++++++ .../application/grid/grid_header_bloc.dart | 8 +++++-- .../plugins/grid/src/grid_page.dart | 22 ++++++++++++++----- .../grid/src/widgets/header/grid_header.dart | 9 +++++++- .../flowy-grid/src/services/grid_editor.rs | 22 +++++++++++++++---- .../src/client_grid/grid_meta_pad.rs | 19 ++++++++++++++++ 6 files changed, 78 insertions(+), 13 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index e1bed697c8..c909bf1b31 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -29,6 +29,17 @@ class FieldService { return GridEventGetEditFieldContext(payload).send(); } + Future> moveField(String fieldId, int fromIndex, int toIndex) { + final payload = MoveItemPayload.create() + ..gridId = gridId + ..itemId = fieldId + ..ty = MoveItemType.MoveField + ..fromIndex = fromIndex + ..toIndex = toIndex; + + return GridEventMoveItem(payload).send(); + } + Future> updateField({ required String fieldId, String? name, diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart index 8ea390d7ab..08cd01e316 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -25,7 +26,10 @@ class GridHeaderBloc extends Bloc { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { emit(state.copyWith(fields: value.fields)); }, - moveField: (_MoveField value) {}, + moveField: (_MoveField value) async { + final result = await _fieldService.moveField(value.field.id, value.fromIndex, value.toIndex); + result.fold((l) {}, (err) => Log.error(err)); + }, ); }, ); @@ -49,7 +53,7 @@ class GridHeaderBloc extends Bloc { class GridHeaderEvent with _$GridHeaderEvent { const factory GridHeaderEvent.initial() = _InitialHeader; const factory GridHeaderEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; - const factory GridHeaderEvent.moveField(int fromIndex, int toIndex) = _MoveField; + const factory GridHeaderEvent.moveField(Field field, int fromIndex, int toIndex) = _MoveField; } @freezed 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 340f7c7026..127a39d024 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 @@ -75,6 +75,13 @@ class FlowyGrid extends StatefulWidget { class _FlowyGridState extends State { final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup()); + late ScrollController headerScrollController; + + @override + void initState() { + headerScrollController = _scrollController.linkHorizontalController(); + super.initState(); + } @override void dispose() { @@ -96,11 +103,14 @@ class _FlowyGridState extends State { ], ); - return Column(children: [ - const _GridToolbarAdaptor(), - _gridHeader(context, state.gridId, contentWidth), - Flexible(child: child), - ]); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const _GridToolbarAdaptor(), + _gridHeader(context, state.gridId, contentWidth), + Flexible(child: child), + ], + ); }, ); } @@ -145,7 +155,7 @@ class _FlowyGridState extends State { child: GridHeaderSliverAdaptor( gridId: gridId, fieldCache: fieldCache, - anchorScrollController: _scrollController.linkHorizontalController(), + anchorScrollController: headerScrollController, ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 2ac5e5f673..95abccc830 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -110,7 +110,7 @@ class _GridHeaderState extends State<_GridHeader> { header: const _CellLeading(), footer: _CellTrailing(gridId: widget.gridId), onReorder: (int oldIndex, int newIndex) { - Log.info("from $oldIndex to $newIndex"); + _onReorder(cells, oldIndex, context, newIndex); }, children: cells, ), @@ -119,6 +119,13 @@ class _GridHeaderState extends State<_GridHeader> { }, ); } + + void _onReorder(List cells, int oldIndex, BuildContext context, int newIndex) { + if (cells.length > oldIndex) { + final field = cells[oldIndex].cellContext.field; + context.read().add(GridHeaderEvent.moveField(field, oldIndex, newIndex)); + } + } } class _CellLeading extends StatelessWidget { 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 41a70d8549..e348d105d1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -385,16 +385,30 @@ impl ClientGridEditor { pub async fn move_item(&self, params: MoveItemParams) -> FlowyResult<()> { match params.ty { MoveItemType::MoveField => { - self.move_field(params.from_index, params.to_index, ¶ms.item_id) + self.move_field(¶ms.item_id, params.from_index, params.to_index) .await } MoveItemType::MoveRow => self.move_row(params.from_index, params.to_index, ¶ms.item_id).await, } } - pub async fn move_field(&self, from: i32, to: i32, field_id: &str) -> FlowyResult<()> { - // GridFieldChangeset - todo!() + pub async fn move_field(&self, field_id: &str, from: i32, to: i32) -> FlowyResult<()> { + let _ = self + .modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?)) + .await?; + if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { + let delete_field_order = FieldOrder::from(field_id); + let insert_field = IndexField::from_field_meta(field_meta, index); + let notified_changeset = GridFieldChangeset { + grid_id: self.grid_id.clone(), + inserted_fields: vec![insert_field], + deleted_fields: vec![delete_field_order], + updated_fields: vec![], + }; + + let _ = self.notify_did_update_grid(notified_changeset).await?; + } + Ok(()) } pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 5c59437d4f..2cf56fd5f0 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -205,6 +205,25 @@ impl GridMetaPad { ) } + pub fn move_field( + &mut self, + field_id: &str, + from_index: usize, + to_index: usize, + ) -> CollaborateResult> { + self.modify_grid( + |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + debug_assert_eq!(index, from_index); + let field_meta = grid_meta.fields.remove(index); + grid_meta.fields.insert(to_index, field_meta); + Ok(Some(())) + } + }, + ) + } + pub fn contain_field(&self, field_id: &str) -> bool { self.grid_meta.fields.iter().any(|field| field.id == field_id) } From ea654b602c73a830ff776a448053a4e07340f9bf Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 15 Apr 2022 22:10:38 +0800 Subject: [PATCH 160/179] fix: listen on listState if changed --- .../lib/workspace/presentation/plugins/grid/src/grid_page.dart | 1 + 1 file changed, 1 insertion(+) 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 127a39d024..189027c277 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 @@ -193,6 +193,7 @@ class _GridRowsState extends State<_GridRows> { @override Widget build(BuildContext context) { return BlocConsumer( + listenWhen: (previous, current) => previous.listState != current.listState, listener: (context, state) { state.listState.map( insert: (value) { From f3c82f5c30a481eb2cba0ac9f61d4f48f5912502 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 15 Apr 2022 22:21:32 +0800 Subject: [PATCH 161/179] chore: insert without remove field on FieldCache --- .../app_flowy/lib/workspace/application/grid/grid_service.dart | 1 - 1 file changed, 1 deletion(-) 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 b79c2e5e59..42f6fa0694 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -103,7 +103,6 @@ class GridFieldCache { final List fields = _fieldNotifier.fields; for (final indexField in insertedFields) { if (fields.length > indexField.index) { - fields.removeAt(indexField.index); fields.insert(indexField.index, indexField.field_1); } else { fields.add(indexField.field_1); From d4de5767a66655541ee55c1ba4f5edf3f3af4fa8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 16 Apr 2022 09:25:12 +0800 Subject: [PATCH 162/179] chore: auto resize row height --- .../application/grid/row/row_service.dart | 11 ++ .../plugins/grid/src/grid_page.dart | 16 +-- .../grid/src/widgets/cell/cell_container.dart | 4 +- .../grid/src/widgets/header/field_cell.dart | 105 ++++++++++++------ .../grid/src/widgets/header/grid_header.dart | 64 ++++++----- .../grid/src/widgets/row/grid_row.dart | 13 ++- .../src/services/block_meta_editor.rs | 23 ++-- .../src/services/block_meta_manager.rs | 26 +++++ .../flowy-grid/src/services/grid_editor.rs | 11 +- .../src/client_grid/grid_block_meta_pad.rs | 13 +++ 10 files changed, 192 insertions(+), 94 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 643a2c649e..412dea9003 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -21,6 +21,17 @@ class RowService { return GridEventCreateRow(payload).send(); } + Future> moveRow(String rowId, int fromIndex, int toIndex) { + final payload = MoveItemPayload.create() + ..gridId = gridId + ..itemId = rowId + ..ty = MoveItemType.MoveRow + ..fromIndex = fromIndex + ..toIndex = toIndex; + + return GridEventMoveItem(payload).send(); + } + Future> getRow() { final payload = RowIdentifierPayload.create() ..gridId = gridId 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 189027c277..1c7707c8eb 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 @@ -107,7 +107,7 @@ class _FlowyGridState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ const _GridToolbarAdaptor(), - _gridHeader(context, state.gridId, contentWidth), + _gridHeader(context, state.gridId), Flexible(child: child), ], ); @@ -147,16 +147,12 @@ class _FlowyGridState extends State { ); } - Widget _gridHeader(BuildContext context, String gridId, double contentWidth) { + Widget _gridHeader(BuildContext context, String gridId) { final fieldCache = context.read().fieldCache; - - return SizedBox( - width: contentWidth, - child: GridHeaderSliverAdaptor( - gridId: gridId, - fieldCache: fieldCache, - anchorScrollController: headerScrollController, - ), + return GridHeaderSliverAdaptor( + gridId: gridId, + fieldCache: fieldCache, + anchorScrollController: headerScrollController, ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index 57f3610be2..0ff4ae71ab 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -33,9 +33,7 @@ class CellContainer extends StatelessWidget { child: Consumer( builder: (context, state, _) { return Container( - constraints: BoxConstraints( - maxWidth: width, - ), + constraints: BoxConstraints(maxWidth: width, maxHeight: 42), decoration: _makeBoxDecoration(context, state), padding: GridSize.cellContentInsets, child: Center(child: child), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index e9fa11d883..c6009b64af 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -6,6 +6,7 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_type_extension.dart'; @@ -28,49 +29,19 @@ class GridFieldCell extends StatelessWidget { final button = FlowyButton( hoverColor: theme.shader6, onTap: () => _showActionSheet(context), - // rightIcon: svgWidget("editor/details", color: theme.iconColor), leftIcon: svgWidget(state.field.fieldType.iconName(), color: theme.iconColor), text: FlowyText.medium(state.field.name, fontSize: 12), padding: GridSize.cellContentInsets, ); - final line = InkWell( - onTap: () {}, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onHorizontalDragCancel: () {}, - onHorizontalDragUpdate: (value) { - context.read().add(FieldCellEvent.updateWidth(value.delta.dx)); - }, - child: FlowyHover( - style: HoverStyle( - hoverColor: theme.main1, - borderRadius: BorderRadius.zero, - contentMargin: const EdgeInsets.only(left: 5), - ), - builder: (_, onHover) => const SizedBox(width: 2), - ), - ), - ); + const line = Positioned(top: 0, bottom: 0, right: 0, child: _DragToExpandLine()); - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - final decoration = BoxDecoration( - border: Border( - top: borderSide, - right: borderSide, - bottom: borderSide, - )); - - return Container( + return _CellContainer( width: state.field.width.toDouble(), - decoration: decoration, - child: ConstrainedBox( - constraints: const BoxConstraints.expand(), - child: Stack( - alignment: Alignment.centerRight, - fit: StackFit.expand, - children: [button, Positioned(top: 0, bottom: 0, right: 0, child: line)], - ), + child: Stack( + alignment: Alignment.centerRight, + fit: StackFit.expand, + children: [button, line], ), ); }, @@ -98,3 +69,65 @@ class GridFieldCell extends StatelessWidget { ).show(context); } } + +class _CellContainer extends StatelessWidget { + final Widget child; + final double width; + const _CellContainer({ + required this.child, + required this.width, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + final decoration = BoxDecoration( + border: Border( + top: borderSide, + right: borderSide, + bottom: borderSide, + )); + + return Container( + width: width, + decoration: decoration, + child: ConstrainedBox(constraints: const BoxConstraints.expand(), child: child), + ); + } +} + +class _DragToExpandLine extends StatelessWidget { + const _DragToExpandLine({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return InkWell( + onTap: () {}, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onHorizontalDragCancel: () {}, + onHorizontalDragUpdate: (value) { + // context.read().add(FieldCellEvent.updateWidth(value.delta.dx)); + Log.info(value); + }, + onHorizontalDragEnd: (end) { + Log.info(end); + }, + child: FlowyHover( + style: HoverStyle( + hoverColor: theme.main1, + borderRadius: BorderRadius.zero, + contentMargin: const EdgeInsets.only(left: 5), + ), + builder: (_, onHover) => const SizedBox(width: 2), + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 95abccc830..22bd59eb4d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -32,15 +32,21 @@ class _GridHeaderSliverAdaptorState extends State { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - getIt(param1: widget.gridId, param2: widget.fieldCache)..add(const GridHeaderEvent.initial()), + create: (context) { + final bloc = getIt(param1: widget.gridId, param2: widget.fieldCache); + bloc.add(const GridHeaderEvent.initial()); + return bloc; + }, child: BlocBuilder( buildWhen: (previous, current) => previous.fields.length != current.fields.length, builder: (context, state) { return SingleChildScrollView( scrollDirection: Axis.horizontal, controller: widget.anchorScrollController, - child: SizedBox(height: GridSize.headerHeight, child: _GridHeader(gridId: widget.gridId)), + child: SizedBox( + height: GridSize.headerHeight, + child: _GridHeader(gridId: widget.gridId), + ), ); // return SliverPersistentHeader( @@ -54,32 +60,6 @@ class _GridHeaderSliverAdaptorState extends State { } } -class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate { - final String gridId; - final List fields; - - SliverHeaderDelegateImplementation({required this.gridId, required this.fields}); - - @override - Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - return _GridHeader(gridId: gridId); - } - - @override - double get maxExtent => GridSize.headerHeight; - - @override - double get minExtent => GridSize.headerHeight; - - @override - bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { - if (oldDelegate is SliverHeaderDelegateImplementation) { - return fields.length != oldDelegate.fields.length; - } - return true; - } -} - class _GridHeader extends StatefulWidget { final String gridId; const _GridHeader({Key? key, required this.gridId}) : super(key: key); @@ -177,3 +157,29 @@ class CreateFieldButton extends StatelessWidget { ); } } + +class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate { + final String gridId; + final List fields; + + SliverHeaderDelegateImplementation({required this.gridId, required this.fields}); + + @override + Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + return _GridHeader(gridId: gridId); + } + + @override + double get maxExtent => GridSize.headerHeight; + + @override + double get minExtent => GridSize.headerHeight; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + if (oldDelegate is SliverHeaderDelegateImplementation) { + return fields.length != oldDelegate.fields.length; + } + return true; + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 5528818a58..b63f79f5b0 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -44,10 +44,11 @@ class _GridRowWidgetState extends State { child: BlocBuilder( buildWhen: (p, c) => p.rowData.height != c.rowData.height, builder: (context, state) { - return SizedBox( - height: _rowBloc.state.rowData.height, + return LimitedBox( + maxHeight: 200, child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, children: const [ _RowLeading(), _RowCells(), @@ -147,7 +148,11 @@ class _RowCells extends StatelessWidget { buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { final List children = state.cellDataMap.fold(() => [], _toCells); - return Row(children: children); + return Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: children, + ); }, ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 652617146b..977ccccb3d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -51,16 +51,16 @@ impl ClientGridBlockMetaEditor { let mut row_count = 0; let mut row_index = None; let _ = self - .modify(|pad| { + .modify(|block_pad| { if let Some(start_row_id) = start_row_id.as_ref() { - match pad.index_of_row(start_row_id) { + match block_pad.index_of_row(start_row_id) { None => {} Some(index) => row_index = Some(index + 1), } } - let change = pad.add_row_meta(row, start_row_id)?; - row_count = pad.number_of_rows(); + let change = block_pad.add_row_meta(row, start_row_id)?; + row_count = block_pad.number_of_rows(); Ok(change) }) .await?; @@ -71,9 +71,9 @@ impl ClientGridBlockMetaEditor { pub async fn delete_rows(&self, ids: Vec>) -> FlowyResult { let mut row_count = 0; let _ = self - .modify(|pad| { - let changeset = pad.delete_rows(ids)?; - row_count = pad.number_of_rows(); + .modify(|block_pad| { + let changeset = block_pad.delete_rows(ids)?; + row_count = block_pad.number_of_rows(); Ok(changeset) }) .await?; @@ -81,7 +81,14 @@ impl ClientGridBlockMetaEditor { } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { - let _ = self.modify(|pad| Ok(pad.update_row(changeset)?)).await?; + let _ = self.modify(|block_pad| Ok(block_pad.update_row(changeset)?)).await?; + Ok(()) + } + + pub async fn move_row(&self, row_id: &str, from: usize, to: usize) -> FlowyResult<()> { + let _ = self + .modify(|block_pad| Ok(block_pad.move_row(row_id, from, to)?)) + .await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index b5a35b10cd..2a8eae4497 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -154,6 +154,32 @@ impl GridBlockMetaEditorManager { Ok(changesets) } + pub(crate) async fn move_row(&self, row_id: &str, from: usize, to: usize) -> FlowyResult<()> { + let editor = self.get_editor_from_row_id(row_id).await?; + let _ = editor.move_row(row_id, from, to).await?; + + match editor.get_row_metas(Some(vec![Cow::Borrowed(row_id)])).await?.pop() { + None => {} + Some(row_meta) => { + let row_order = RowOrder::from(&row_meta); + let insert_row = IndexRowOrder { + row_order: row_order.clone(), + index: Some(to as i32), + }; + let notified_changeset = GridRowsChangeset { + block_id: editor.block_id.clone(), + inserted_rows: vec![insert_row], + deleted_rows: vec![row_order], + updated_rows: vec![], + }; + + let _ = self.notify_did_update_rows(notified_changeset).await?; + } + } + + Ok(()) + } + pub async fn update_cell(&self, changeset: CellChangeset) -> FlowyResult<()> { let row_id = changeset.row_id.clone(); let editor = self.get_editor_from_row_id(&row_id).await?; 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 e348d105d1..b34e0fea65 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -388,7 +388,7 @@ impl ClientGridEditor { self.move_field(¶ms.item_id, params.from_index, params.to_index) .await } - MoveItemType::MoveRow => self.move_row(params.from_index, params.to_index, ¶ms.item_id).await, + MoveItemType::MoveRow => self.move_row(¶ms.item_id, params.from_index, params.to_index).await, } } @@ -411,9 +411,12 @@ impl ClientGridEditor { Ok(()) } - pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> { - // GridRowsChangeset - todo!() + pub async fn move_row(&self, row_id: &str, from: i32, to: i32) -> FlowyResult<()> { + let _ = self + .block_meta_manager + .move_row(row_id, from as usize, to as usize) + .await?; + Ok(()) } pub async fn delta_bytes(&self) -> Bytes { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 1a51b1bebb..3f727faf59 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -149,6 +149,19 @@ impl GridBlockMetaPad { }) } + pub fn move_row(&mut self, row_id: &str, from: usize, to: usize) -> CollaborateResult> { + self.modify(|row_metas| { + if let Some(position) = row_metas.iter().position(|row_meta| row_meta.id == row_id) { + debug_assert_eq!(from, position); + let row_meta = row_metas.remove(position); + row_metas.insert(to, row_meta); + Ok(Some(())) + } else { + Ok(None) + } + }) + } + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, From 792f8b95aaf219ec8abd77563b76406de807b333 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 16 Apr 2022 16:58:26 +0800 Subject: [PATCH 163/179] fix: triger rowbloc event after it was closed --- .../application/grid/grid_service.dart | 15 +++++++----- .../application/grid/row/row_bloc.dart | 24 ++++++++++++++----- .../plugins/grid/src/grid_page.dart | 12 +++++----- .../grid/src/widgets/cell/cell_container.dart | 2 +- .../grid/src/widgets/row/grid_row.dart | 4 ++-- 5 files changed, 36 insertions(+), 21 deletions(-) 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 42f6fa0694..0f2118fea1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -162,7 +162,7 @@ class GridRowCache { } final List newRows = []; - final List> deletedIndex = []; + final DeletedIndex deletedIndex = []; final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; _rows.asMap().forEach((index, value) { if (deletedRowMap[value.rowId] == null) { @@ -181,13 +181,13 @@ class GridRowCache { return none(); } - List insertIndexs = []; + InsertedIndexs insertIndexs = []; for (final newRow in createdRows) { if (newRow.hasIndex()) { - insertIndexs.add(newRow.index); + insertIndexs.add(Tuple2(newRow.index, newRow.rowOrder.rowId)); _rows.insert(newRow.index, _toRowData(newRow.rowOrder)); } else { - insertIndexs.add(_rows.length); + insertIndexs.add(Tuple2(newRow.index, newRow.rowOrder.rowId)); _rows.add(_toRowData(newRow.rowOrder)); } } @@ -216,9 +216,12 @@ class GridRowCache { } } +typedef InsertedIndexs = List>; +typedef DeletedIndex = List>; + @freezed class GridListState with _$GridListState { - const factory GridListState.insert(List indexs) = _Insert; - const factory GridListState.delete(List> indexs) = _Delete; + const factory GridListState.insert(InsertedIndexs items) = _Insert; + const factory GridListState.delete(DeletedIndex items) = _Delete; const factory GridListState.initial() = InitialListState; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index b16d75dc92..81bb8b190c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -35,20 +35,23 @@ class RowBloc extends Bloc { _rowService.createRow(); }, didUpdateRow: (_DidUpdateRow value) async { - _handleRowUpdate(value, emit); + _handleRowUpdate(value.row, emit); }, fieldsDidUpdate: (_FieldsDidUpdate value) async { await _handleFieldUpdate(emit); }, + didLoadRow: (_DidLoadRow value) { + _handleRowUpdate(value.row, emit); + }, ); }, ); } - void _handleRowUpdate(_DidUpdateRow value, Emitter emit) { - final CellDataMap cellDataMap = _makeCellDatas(value.row, state.rowData.fields); + void _handleRowUpdate(Row row, Emitter emit) { + final CellDataMap cellDataMap = _makeCellDatas(row, state.rowData.fields); emit(state.copyWith( - row: Future(() => Some(value.row)), + row: Future(() => Some(row)), cellDataMap: Some(cellDataMap), )); } @@ -75,7 +78,11 @@ class RowBloc extends Bloc { Future _startListening() async { _rowlistener.updateRowNotifier?.addPublishListener((result) { result.fold( - (row) => add(RowEvent.didUpdateRow(row)), + (row) { + if (!isClosed) { + add(RowEvent.didUpdateRow(row)); + } + }, (err) => Log.error(err), ); }); @@ -92,7 +99,11 @@ class RowBloc extends Bloc { Future _loadRow(Emitter emit) async { _rowService.getRow().then((result) { return result.fold( - (row) => add(RowEvent.didUpdateRow(row)), + (row) { + if (!isClosed) { + add(RowEvent.didLoadRow(row)); + } + }, (err) => Log.error(err), ); }); @@ -119,6 +130,7 @@ class RowEvent with _$RowEvent { const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.fieldsDidUpdate() = _FieldsDidUpdate; + const factory RowEvent.didLoadRow(Row row) = _DidLoadRow; const factory RowEvent.didUpdateRow(Row row) = _DidUpdateRow; } 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 1c7707c8eb..74215f4b80 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -6,7 +6,6 @@ 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' show Field; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; import 'package:linked_scroll_controller/linked_scroll_controller.dart'; @@ -193,15 +192,15 @@ class _GridRowsState extends State<_GridRows> { listener: (context, state) { state.listState.map( insert: (value) { - for (final index in value.indexs) { - _key.currentState?.insertItem(index); + for (final item in value.items) { + _key.currentState?.insertItem(item.value1); } }, delete: (value) { - for (final index in value.indexs) { + for (final item in value.items) { _key.currentState?.removeItem( - index.value1, - (context, animation) => _renderRow(context, index.value2, animation), + item.value1, + (context, animation) => _renderRow(context, item.value2, animation), ); } }, @@ -224,6 +223,7 @@ class _GridRowsState extends State<_GridRows> { Widget _renderRow(BuildContext context, RowData rowData, Animation animation) { final fieldCache = context.read().fieldCache; + return SizeTransition( sizeFactor: animation, child: GridRowWidget( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index 0ff4ae71ab..c9af10c2b8 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -33,7 +33,7 @@ class CellContainer extends StatelessWidget { child: Consumer( builder: (context, state, _) { return Container( - constraints: BoxConstraints(maxWidth: width, maxHeight: 42), + constraints: BoxConstraints(maxWidth: width), decoration: _makeBoxDecoration(context, state), padding: GridSize.cellContentInsets, child: Center(child: child), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index b63f79f5b0..edac8bc2fe 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -44,8 +44,8 @@ class _GridRowWidgetState extends State { child: BlocBuilder( buildWhen: (p, c) => p.rowData.height != c.rowData.height, builder: (context, state) { - return LimitedBox( - maxHeight: 200, + return SizedBox( + height: 42, child: Row( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, From 3cc7c8e6de67ba642bd90d202c4ad834e479f9be Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 16 Apr 2022 20:20:00 +0800 Subject: [PATCH 164/179] chore: cache row data --- .../app_flowy/lib/startup/deps_resolver.dart | 7 - .../grid/cell_bloc/checkbox_cell_bloc.dart | 9 +- .../grid/cell_bloc/date_cell_bloc.dart | 19 +-- .../grid/cell_bloc/number_cell_bloc.dart | 10 +- .../grid/cell_bloc/selection_cell_bloc.dart | 15 +- .../grid/cell_bloc/selection_editor_bloc.dart | 23 ++- .../grid/field/field_cell_bloc.dart | 8 +- .../workspace/application/grid/grid_bloc.dart | 26 ++-- .../application/grid/grid_header_bloc.dart | 10 +- .../application/grid/grid_service.dart | 105 +------------- .../grid/row/row_action_sheet_bloc.dart | 6 +- .../application/grid/row/row_bloc.dart | 58 ++++---- .../application/grid/row/row_service.dart | 136 +++++++++++++++++- .../plugins/grid/src/grid_page.dart | 14 +- .../grid/src/widgets/row/grid_row.dart | 12 +- .../src/widgets/row/row_action_sheet.dart | 2 +- .../packages/flowy_infra/lib/notifier.dart | 12 +- 17 files changed, 247 insertions(+), 225 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index e35f8e7f96..47267cc2c9 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -150,13 +150,6 @@ void _resolveGridDeps(GetIt getIt) { (view, _) => GridBloc(view: view), ); - getIt.registerFactoryParam( - (data, fieldCache) => RowBloc( - rowData: data, - fieldCache: fieldCache, - ), - ); - getIt.registerFactoryParam( (gridId, fieldCache) => GridHeaderBloc( gridId: gridId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 2d937b8cd2..3a4500eb45 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -58,12 +58,11 @@ class CheckboxCellBloc extends Bloc { fieldId: state.cellData.field.id, rowId: state.cellData.rowId, ); + if (isClosed) { + return; + } result.fold( - (cell) { - if (!isClosed) { - add(CheckboxCellEvent.didReceiveCellUpdate(cell)); - } - }, + (cell) => add(CheckboxCellEvent.didReceiveCellUpdate(cell)), (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index b4b6d7e152..d7e0c078aa 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -57,19 +57,15 @@ class DateCellBloc extends Bloc { (notificationData) => _loadCellData(), (err) => Log.error(err), ); - }); + }, listenWhen: () => !isClosed); _cellListener.start(); _fieldListener.updateFieldNotifier?.addPublishListener((result) { result.fold( - (field) { - if (!isClosed) { - add(DateCellEvent.didReceiveFieldUpdate(field)); - } - }, + (field) => add(DateCellEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); - }); + }, listenWhen: () => !isClosed); _fieldListener.start(); } @@ -79,12 +75,11 @@ class DateCellBloc extends Bloc { fieldId: state.cellData.field.id, rowId: state.cellData.rowId, ); + if (isClosed) { + return; + } result.fold( - (cell) { - if (!isClosed) { - add(DateCellEvent.didReceiveCellUpdate(cell)); - } - }, + (cell) => add(DateCellEvent.didReceiveCellUpdate(cell)), (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index 287d70b701..fbc432c557 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -84,12 +84,12 @@ class NumberCellBloc extends Bloc { fieldId: state.cellData.field.id, rowId: state.cellData.rowId, ); + + if (isClosed) { + return; + } result.fold( - (cell) { - if (!isClosed) { - add(NumberCellEvent.didReceiveCellUpdate(cell)); - } - }, + (cell) => add(NumberCellEvent.didReceiveCellUpdate(cell)), (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index dbca1b5ae3..ae7c48d81f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -49,16 +49,15 @@ class SelectionCellBloc extends Bloc { fieldId: state.cellData.field.id, rowId: state.cellData.rowId, ); + if (isClosed) { + return; + } result.fold( - (selectOptionContext) { - if (!isClosed) { - add(SelectionCellEvent.didReceiveOptions( - selectOptionContext.options, - selectOptionContext.selectOptions, - )); - } - }, + (selectOptionContext) => add(SelectionCellEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )), (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 813b779646..0d1b2705e3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -117,16 +117,15 @@ class SelectOptionEditorBloc extends Bloc add(SelectOptionEditorEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )), (err) => Log.error(err), ); }, @@ -144,14 +143,10 @@ class SelectOptionEditorBloc extends Bloc add(SelectOptionEditorEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); - }); + }, listenWhen: () => !isClosed); _fieldListener.start(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart index 2c148ae452..576e62e3b1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -47,14 +47,10 @@ class FieldCellBloc extends Bloc { void _startListening() { _fieldListener.updateFieldNotifier?.addPublishListener((result) { result.fold( - (field) { - if (!isClosed) { - add(FieldCellEvent.didReceiveFieldUpdate(field)); - } - }, + (field) => add(FieldCellEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); - }); + }, listenWhen: () => !isClosed); _fieldListener.start(); } } 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 c37c31ec46..5782371e7a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -18,14 +18,14 @@ class GridBloc extends Bloc { final GridListener _gridListener; final GridFieldsListener _fieldListener; final GridFieldCache fieldCache; - final GridRowCache _rowCache; + final GridRowCache rowCache; GridBloc({required View view}) : _fieldListener = GridFieldsListener(gridId: view.id), _gridService = GridService(gridId: view.id), _gridListener = GridListener(gridId: view.id), fieldCache = GridFieldCache(), - _rowCache = GridRowCache(gridId: view.id), + rowCache = GridRowCache(gridId: view.id), super(GridState.initial(view.id)) { on( (event, emit) async { @@ -41,7 +41,7 @@ class GridBloc extends Bloc { emit(state.copyWith(rows: value.rows, listState: value.listState)); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - emit(state.copyWith(rows: _rowCache.rows, fields: value.fields)); + emit(state.copyWith(rows: rowCache.rows, fields: value.fields)); }, ); }, @@ -62,7 +62,7 @@ class GridBloc extends Bloc { result.fold( (changeset) { fieldCache.applyChangeset(changeset); - _rowCache.updateFields(fieldCache.unmodifiableFields); + rowCache.updateFields(fieldCache.unmodifiableFields); add(GridEvent.didReceiveFieldUpdate(fieldCache.clonedFields)); }, (err) => Log.error(err), @@ -74,15 +74,15 @@ class GridBloc extends Bloc { result.fold( (changesets) { for (final changeset in changesets) { - _rowCache + rowCache .deleteRows(changeset.deletedRows) - .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(_rowCache.rows, listState))); + .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(rowCache.rows, listState))); - _rowCache + rowCache .insertRows(changeset.insertedRows) - .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(_rowCache.rows, listState))); + .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(rowCache.rows, listState))); - _rowCache.updateRows(changeset.updatedRows); + rowCache.updateRows(changeset.updatedRows); } }, (err) => Log.error(err), @@ -107,12 +107,12 @@ class GridBloc extends Bloc { () => result.fold( (fields) { fieldCache.clonedFields = fields.items; - _rowCache.updateWithBlock(grid.blockOrders, fieldCache.unmodifiableFields); + rowCache.updateWithBlock(grid.blockOrders, fieldCache.unmodifiableFields); emit(state.copyWith( grid: Some(grid), fields: fieldCache.clonedFields, - rows: _rowCache.rows, + rows: rowCache.rows, loadingState: GridLoadingState.finish(left(unit)), )); }, @@ -126,7 +126,7 @@ class GridBloc extends Bloc { class GridEvent with _$GridEvent { const factory GridEvent.initial() = InitialGrid; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.didReceiveRowUpdate(List rows, GridListState listState) = _DidReceiveRowUpdate; + const factory GridEvent.didReceiveRowUpdate(List rows, GridListState listState) = _DidReceiveRowUpdate; const factory GridEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @@ -136,7 +136,7 @@ class GridState with _$GridState { required String gridId, required Option grid, required List fields, - required List rows, + required List rows, required GridLoadingState loadingState, required GridListState listState, }) = _GridState; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart index 08cd01e316..aa4d7343b9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -36,11 +36,11 @@ class GridHeaderBloc extends Bloc { } Future _startListening() async { - fieldCache.addListener(() {}, onChanged: (fields) { - if (!isClosed) { - add(GridHeaderEvent.didReceiveFieldUpdate(fields)); - } - }); + fieldCache.addListener( + () {}, + onChanged: (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), + listenWhen: () => !isClosed, + ); } @override 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 0f2118fea1..441ce4c963 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -5,9 +5,6 @@ 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/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; - -part 'grid_service.freezed.dart'; class GridService { final String gridId; @@ -74,11 +71,16 @@ class GridFieldCache { _fieldNotifier.addListener(() => onFieldChanged(clonedFields)); } - void addListener(VoidCallback listener, {void Function(List)? onChanged}) { + void addListener(VoidCallback listener, {void Function(List)? onChanged, bool Function()? listenWhen}) { _fieldNotifier.addListener(() { if (onChanged != null) { onChanged(clonedFields); } + + if (listenWhen != null && listenWhen() == false) { + return; + } + listener(); }); } @@ -130,98 +132,3 @@ class GridFieldCache { _fieldNotifier.dispose(); } } - -class GridRowCache { - final String gridId; - UnmodifiableListView _fields = UnmodifiableListView([]); - List _rows = []; - - GridRowCache({required this.gridId}); - - List get rows => [..._rows]; - - void updateWithBlock(List blocks, UnmodifiableListView fields) { - _fields = fields; - _rows = blocks.expand((block) => block.rowOrders).map((rowOrder) { - return RowData.fromBlockRow(gridId, rowOrder, _fields); - }).toList(); - } - - void updateFields(UnmodifiableListView fields) { - if (fields.isEmpty) { - return; - } - - _fields = fields; - _rows = _rows.map((row) => row.copyWith(fields: fields)).toList(); - } - - Option deleteRows(List deletedRows) { - if (deletedRows.isEmpty) { - return none(); - } - - final List newRows = []; - final DeletedIndex deletedIndex = []; - final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; - _rows.asMap().forEach((index, value) { - if (deletedRowMap[value.rowId] == null) { - newRows.add(value); - } else { - deletedIndex.add(Tuple2(index, value)); - } - }); - _rows = newRows; - - return Some(GridListState.delete(deletedIndex)); - } - - Option insertRows(List createdRows) { - if (createdRows.isEmpty) { - return none(); - } - - InsertedIndexs insertIndexs = []; - for (final newRow in createdRows) { - if (newRow.hasIndex()) { - insertIndexs.add(Tuple2(newRow.index, newRow.rowOrder.rowId)); - _rows.insert(newRow.index, _toRowData(newRow.rowOrder)); - } else { - insertIndexs.add(Tuple2(newRow.index, newRow.rowOrder.rowId)); - _rows.add(_toRowData(newRow.rowOrder)); - } - } - - return Some(GridListState.insert(insertIndexs)); - } - - void updateRows(List updatedRows) { - if (updatedRows.isEmpty) { - return; - } - - final List updatedIndexs = []; - for (final updatedRow in updatedRows) { - final index = _rows.indexWhere((row) => row.rowId == updatedRow.rowId); - if (index != -1) { - _rows.removeAt(index); - _rows.insert(index, _toRowData(updatedRow)); - updatedIndexs.add(index); - } - } - } - - RowData _toRowData(RowOrder rowOrder) { - return RowData.fromBlockRow(gridId, rowOrder, _fields); - } -} - -typedef InsertedIndexs = List>; -typedef DeletedIndex = List>; - -@freezed -class GridListState with _$GridListState { - const factory GridListState.insert(InsertedIndexs items) = _Insert; - const factory GridListState.delete(DeletedIndex items) = _Delete; - const factory GridListState.initial() = InitialListState; -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart index 93ee70afa0..16f8679b2c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart @@ -11,7 +11,7 @@ part 'row_action_sheet_bloc.freezed.dart'; class RowActionSheetBloc extends Bloc { final RowService _rowService; - RowActionSheetBloc({required RowData rowData}) + RowActionSheetBloc({required GridRow rowData}) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), super(RowActionSheetState.initial(rowData)) { on( @@ -49,10 +49,10 @@ class RowActionSheetEvent with _$RowActionSheetEvent { @freezed class RowActionSheetState with _$RowActionSheetState { const factory RowActionSheetState({ - required RowData rowData, + required GridRow rowData, }) = _RowActionSheetState; - factory RowActionSheetState.initial(RowData rowData) => RowActionSheetState( + factory RowActionSheetState.initial(GridRow rowData) => RowActionSheetState( rowData: rowData, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 81bb8b190c..e27c3a7b29 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -18,11 +18,16 @@ class RowBloc extends Bloc { final RowService _rowService; final RowListener _rowlistener; final GridFieldCache _fieldCache; + final GridRowCache _rowCache; - RowBloc({required RowData rowData, required GridFieldCache fieldCache}) - : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), - _fieldCache = fieldCache, + RowBloc({ + required GridRow rowData, + required GridFieldCache fieldCache, + required GridRowCache rowCache, + }) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), _rowlistener = RowListener(rowId: rowData.rowId), + _fieldCache = fieldCache, + _rowCache = rowCache, super(RowState.initial(rowData)) { on( (event, emit) async { @@ -76,37 +81,30 @@ class RowBloc extends Bloc { } Future _startListening() async { - _rowlistener.updateRowNotifier?.addPublishListener((result) { - result.fold( - (row) { - if (!isClosed) { - add(RowEvent.didUpdateRow(row)); - } - }, - (err) => Log.error(err), - ); - }); + _rowlistener.updateRowNotifier?.addPublishListener( + (result) { + result.fold( + (row) => add(RowEvent.didUpdateRow(row)), + (err) => Log.error(err), + ); + }, + listenWhen: () => !isClosed, + ); - _fieldCache.addListener(() { - if (!isClosed) { - add(const RowEvent.fieldsDidUpdate()); - } - }); + _fieldCache.addListener( + () => add(const RowEvent.fieldsDidUpdate()), + listenWhen: () => !isClosed, + ); _rowlistener.start(); } Future _loadRow(Emitter emit) async { - _rowService.getRow().then((result) { - return result.fold( - (row) { - if (!isClosed) { - add(RowEvent.didLoadRow(row)); - } - }, - (err) => Log.error(err), - ); - }); + final data = await _rowCache.getRowData(state.rowData.rowId); + if (isClosed) { + return; + } + data.foldRight(null, (data, _) => add(RowEvent.didLoadRow(data))); } CellDataMap _makeCellDatas(Row row, List fields) { @@ -137,12 +135,12 @@ class RowEvent with _$RowEvent { @freezed class RowState with _$RowState { const factory RowState({ - required RowData rowData, + required GridRow rowData, required Future> row, required Option cellDataMap, }) = _RowState; - factory RowState.initial(RowData rowData) => RowState( + factory RowState.initial(GridRow rowData) => RowState( rowData: rowData, row: Future(() => none()), cellDataMap: none(), diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 412dea9003..25985cb924 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,5 +1,8 @@ +import 'dart:collection'; + import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; @@ -57,6 +60,115 @@ class RowService { } } +class GridRowCache { + final String gridId; + UnmodifiableListView _fields = UnmodifiableListView([]); + HashMap rowDataMap = HashMap(); + + List _rows = []; + + GridRowCache({required this.gridId}); + + List get rows => [..._rows]; + + Future> getRowData(String rowId) async { + final Row? data = rowDataMap[rowId]; + if (data != null) { + return Future(() => Some(data)); + } + + final payload = RowIdentifierPayload.create() + ..gridId = gridId + ..rowId = rowId; + + final result = await GridEventGetRow(payload).send(); + return Future(() { + return result.fold( + (data) { + data.freeze(); + rowDataMap[data.id] = data; + return Some(data); + }, + (err) { + Log.error(err); + return none(); + }, + ); + }); + } + + void updateWithBlock(List blocks, UnmodifiableListView fields) { + _fields = fields; + _rows = blocks.expand((block) => block.rowOrders).map((rowOrder) { + return GridRow.fromBlockRow(gridId, rowOrder, _fields); + }).toList(); + } + + void updateFields(UnmodifiableListView fields) { + if (fields.isEmpty) { + return; + } + + _fields = fields; + _rows = _rows.map((row) => row.copyWith(fields: fields)).toList(); + } + + Option deleteRows(List deletedRows) { + if (deletedRows.isEmpty) { + return none(); + } + + final List newRows = []; + final DeletedIndex deletedIndex = []; + final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; + _rows.asMap().forEach((index, value) { + if (deletedRowMap[value.rowId] == null) { + newRows.add(value); + } else { + deletedIndex.add(Tuple2(index, value)); + } + }); + _rows = newRows; + + return Some(GridListState.delete(deletedIndex)); + } + + Option insertRows(List createdRows) { + if (createdRows.isEmpty) { + return none(); + } + + InsertedIndexs insertIndexs = []; + for (final createdRow in createdRows) { + final gridRow = GridRow.fromBlockRow(gridId, createdRow.rowOrder, _fields); + insertIndexs.add(Tuple2(createdRow.index, gridRow.rowId)); + _rows.insert(createdRow.index, gridRow); + } + + return Some(GridListState.insert(insertIndexs)); + } + + void updateRows(List updatedRows) { + if (updatedRows.isEmpty) { + return; + } + + final List updatedIndexs = []; + for (final updatedRow in updatedRows) { + final index = _rows.indexWhere((row) => row.rowId == updatedRow.rowId); + if (index != -1) { + _rows.removeAt(index); + _rows.insert(index, _toRowData(updatedRow)); + updatedIndexs.add(index); + } + } + } + + GridRow _toRowData(RowOrder rowOrder) { + return GridRow.fromBlockRow(gridId, rowOrder, _fields); + } +} + @freezed class CellData with _$CellData { const factory CellData({ @@ -68,20 +180,32 @@ class CellData with _$CellData { } @freezed -class RowData with _$RowData { - const factory RowData({ +class GridRow with _$GridRow { + const factory GridRow({ required String gridId, required String rowId, required List fields, required double height, - }) = _RowData; + required Future> data, + }) = _GridRow; - factory RowData.fromBlockRow(String gridId, RowOrder row, List fields) { - return RowData( + factory GridRow.fromBlockRow(String gridId, RowOrder row, List fields) { + return GridRow( gridId: gridId, - rowId: row.rowId, fields: fields, + rowId: row.rowId, + data: Future(() => none()), height: row.height.toDouble(), ); } } + +typedef InsertedIndexs = List>; +typedef DeletedIndex = List>; + +@freezed +class GridListState with _$GridListState { + const factory GridListState.insert(InsertedIndexs items) = _Insert; + const factory GridListState.delete(DeletedIndex items) = _Delete; + const factory GridListState.initial() = InitialListState; +} 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 74215f4b80..1acdf5db2f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; @@ -221,14 +222,19 @@ class _GridRowsState extends State<_GridRows> { ); } - Widget _renderRow(BuildContext context, RowData rowData, Animation animation) { - final fieldCache = context.read().fieldCache; + Widget _renderRow(BuildContext context, GridRow rowData, Animation animation) { + final bloc = context.read(); + final fieldCache = bloc.fieldCache; + final rowCache = bloc.rowCache; return SizeTransition( sizeFactor: animation, child: GridRowWidget( - data: rowData, - fieldCache: fieldCache, + blocBuilder: () => RowBloc( + rowData: rowData, + fieldCache: fieldCache, + rowCache: rowCache, + ), key: ValueKey(rowData.rowId), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index edac8bc2fe..6a22c88ca5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -12,9 +12,12 @@ import 'package:provider/provider.dart'; import 'row_action_sheet.dart'; class GridRowWidget extends StatefulWidget { - final RowData data; - final GridFieldCache fieldCache; - const GridRowWidget({required this.data, required this.fieldCache, Key? key}) : super(key: key); + final RowBloc Function() blocBuilder; + + const GridRowWidget({ + required this.blocBuilder, + Key? key, + }) : super(key: key); @override State createState() => _GridRowWidgetState(); @@ -26,7 +29,8 @@ class _GridRowWidgetState extends State { @override void initState() { - _rowBloc = getIt(param1: widget.data, param2: widget.fieldCache)..add(const RowEvent.initial()); + _rowBloc = widget.blocBuilder(); + _rowBloc.add(const RowEvent.initial()); _rowStateNotifier = _RegionStateNotifier(); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart index 458e934756..40e77d9c43 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_action_sheet.dart @@ -14,7 +14,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class GridRowActionSheet extends StatelessWidget { - final RowData rowData; + final GridRow rowData; const GridRowActionSheet({required this.rowData, Key? key}) : super(key: key); @override diff --git a/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart b/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart index 0079ba51a1..7eaf139f0c 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/notifier.dart @@ -31,12 +31,18 @@ class PublishNotifier extends ChangeNotifier { T? get currentValue => _value; - void addPublishListener(void Function(T) callback) { + void addPublishListener(void Function(T) callback, {bool Function()? listenWhen}) { super.addListener( () { - if (_value != null) { - callback(_value!); + if (_value == null) { + return; } + + if (listenWhen != null && listenWhen() == false) { + return; + } + + callback(_value!); }, ); } From c82754f284ea15bb3fd61e02150e8ed5246090a7 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 16 Apr 2022 22:26:34 +0800 Subject: [PATCH 165/179] chore: refactor row cache with row listener --- .../workspace/application/grid/grid_bloc.dart | 63 +++------ .../application/grid/grid_header_bloc.dart | 1 - .../application/grid/grid_listener.dart | 4 +- .../application/grid/grid_service.dart | 56 ++++---- .../application/grid/row/row_bloc.dart | 2 +- .../application/grid/row/row_service.dart | 123 ++++++++++++------ .../grid/setting/property_bloc.dart | 22 +--- .../plugins/grid/src/grid_page.dart | 3 +- .../grid/src/widgets/header/grid_header.dart | 1 - .../grid/src/widgets/row/grid_row.dart | 1 - .../src/client_grid/grid_meta_pad.rs | 2 +- 11 files changed, 148 insertions(+), 130 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 5782371e7a..4d54081980 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,13 +1,10 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'field/grid_listenr.dart'; -import 'grid_listener.dart'; import 'grid_service.dart'; import 'row/row_service.dart'; @@ -15,16 +12,12 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final GridService _gridService; - final GridListener _gridListener; - final GridFieldsListener _fieldListener; final GridFieldCache fieldCache; final GridRowCache rowCache; GridBloc({required View view}) - : _fieldListener = GridFieldsListener(gridId: view.id), - _gridService = GridService(gridId: view.id), - _gridListener = GridListener(gridId: view.id), - fieldCache = GridFieldCache(), + : _gridService = GridService(gridId: view.id), + fieldCache = GridFieldCache(gridId: view.id), rowCache = GridRowCache(gridId: view.id), super(GridState.initial(view.id)) { on( @@ -41,7 +34,7 @@ class GridBloc extends Bloc { emit(state.copyWith(rows: value.rows, listState: value.listState)); }, didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { - emit(state.copyWith(rows: rowCache.rows, fields: value.fields)); + emit(state.copyWith(rows: rowCache.clonedRows, fields: value.fields)); }, ); }, @@ -51,44 +44,22 @@ class GridBloc extends Bloc { @override Future close() async { await _gridService.closeGrid(); - await _fieldListener.stop(); - await _gridListener.stop(); + await fieldCache.dispose(); + await rowCache.dispose(); fieldCache.dispose(); return super.close(); } void _startListening() { - _fieldListener.updateFieldsNotifier?.addPublishListener((result) { - result.fold( - (changeset) { - fieldCache.applyChangeset(changeset); - rowCache.updateFields(fieldCache.unmodifiableFields); - add(GridEvent.didReceiveFieldUpdate(fieldCache.clonedFields)); - }, - (err) => Log.error(err), - ); - }); - _fieldListener.start(); + fieldCache.addListener( + onChanged: (fields) => add(GridEvent.didReceiveFieldUpdate(fields)), + listenWhen: () => !isClosed, + ); - _gridListener.rowsUpdateNotifier.addPublishListener((result) { - result.fold( - (changesets) { - for (final changeset in changesets) { - rowCache - .deleteRows(changeset.deletedRows) - .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(rowCache.rows, listState))); - - rowCache - .insertRows(changeset.insertedRows) - .foldRight(null, (listState, _) => add(GridEvent.didReceiveRowUpdate(rowCache.rows, listState))); - - rowCache.updateRows(changeset.updatedRows); - } - }, - (err) => Log.error(err), - ); - }); - _gridListener.start(); + rowCache.addListener( + onChanged: (rows, listState) => add(GridEvent.didReceiveRowUpdate(rowCache.clonedRows, listState)), + listenWhen: () => !isClosed, + ); } Future _loadGrid(Emitter emit) async { @@ -106,13 +77,13 @@ class GridBloc extends Bloc { return Future( () => result.fold( (fields) { - fieldCache.clonedFields = fields.items; + fieldCache.fields = fields.items; rowCache.updateWithBlock(grid.blockOrders, fieldCache.unmodifiableFields); emit(state.copyWith( grid: Some(grid), fields: fieldCache.clonedFields, - rows: rowCache.rows, + rows: rowCache.clonedRows, loadingState: GridLoadingState.finish(left(unit)), )); }, @@ -126,7 +97,7 @@ class GridBloc extends Bloc { class GridEvent with _$GridEvent { const factory GridEvent.initial() = InitialGrid; const factory GridEvent.createRow() = _CreateRow; - const factory GridEvent.didReceiveRowUpdate(List rows, GridListState listState) = _DidReceiveRowUpdate; + const factory GridEvent.didReceiveRowUpdate(List rows, GridRowChangeReason listState) = _DidReceiveRowUpdate; const factory GridEvent.didReceiveFieldUpdate(List fields) = _DidReceiveFieldUpdate; } @@ -138,7 +109,7 @@ class GridState with _$GridState { required List fields, required List rows, required GridLoadingState loadingState, - required GridListState listState, + required GridRowChangeReason listState, }) = _GridState; factory GridState.initial(String gridId) => GridState( diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart index aa4d7343b9..90007ba8c2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart @@ -37,7 +37,6 @@ class GridHeaderBloc extends Bloc { Future _startListening() async { fieldCache.addListener( - () {}, onChanged: (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), listenWhen: () => !isClosed, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index 862cd95d74..fcff6fa15f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -7,12 +7,12 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -class GridListener { +class GridRowListener { final String gridId; PublishNotifier, FlowyError>> rowsUpdateNotifier = PublishNotifier(comparable: null); GridNotificationListener? _listener; - GridListener({required this.gridId}); + GridRowListener({required this.gridId}); void start() { _listener = GridNotificationListener( 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 441ce4c963..0d24e9974c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -1,5 +1,7 @@ +import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; @@ -50,42 +52,56 @@ class FieldsNotifier extends ChangeNotifier { } class GridFieldCache { + final String gridId; + late final GridFieldsListener _fieldListener; final FieldsNotifier _fieldNotifier = FieldsNotifier(); - GridFieldCache(); - - void applyChangeset(GridFieldChangeset changeset) { - _removeFields(changeset.deletedFields); - _insertFields(changeset.insertedFields); - _updateFields(changeset.updatedFields); + GridFieldCache({required this.gridId}) { + _fieldListener = GridFieldsListener(gridId: gridId); + _fieldListener.updateFieldsNotifier?.addPublishListener((result) { + result.fold( + (changeset) { + _deleteFields(changeset.deletedFields); + _insertFields(changeset.insertedFields); + _updateFields(changeset.updatedFields); + }, + (err) => Log.error(err), + ); + }); + _fieldListener.start(); } + Future dispose() async { + await _fieldListener.stop(); + _fieldNotifier.dispose(); + } + + void applyChangeset(GridFieldChangeset changeset) {} + UnmodifiableListView get unmodifiableFields => UnmodifiableListView(_fieldNotifier.fields); List get clonedFields => [..._fieldNotifier.fields]; - set clonedFields(List fields) { + set fields(List fields) { _fieldNotifier.fields = [...fields]; } - void listenOnFieldChanged(void Function(List) onFieldChanged) { - _fieldNotifier.addListener(() => onFieldChanged(clonedFields)); - } - - void addListener(VoidCallback listener, {void Function(List)? onChanged, bool Function()? listenWhen}) { + void addListener({VoidCallback? listener, void Function(List)? onChanged, bool Function()? listenWhen}) { _fieldNotifier.addListener(() { - if (onChanged != null) { - onChanged(clonedFields); - } - if (listenWhen != null && listenWhen() == false) { return; } - listener(); + if (onChanged != null) { + onChanged(clonedFields); + } + + if (listener != null) { + listener(); + } }); } - void _removeFields(List deletedFields) { + void _deleteFields(List deletedFields) { if (deletedFields.isEmpty) { return; } @@ -127,8 +143,4 @@ class GridFieldCache { } _fieldNotifier.fields = fields; } - - void dispose() { - _fieldNotifier.dispose(); - } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index e27c3a7b29..4ec7ce3a17 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -92,7 +92,7 @@ class RowBloc extends Bloc { ); _fieldCache.addListener( - () => add(const RowEvent.fieldsDidUpdate()), + listener: () => add(const RowEvent.fieldsDidUpdate()), listenWhen: () => !isClosed, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 25985cb924..23cecb1489 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,11 +1,13 @@ import 'dart:collection'; +import 'package:app_flowy/workspace/application/grid/grid_listener.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; +import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'row_service.freezed.dart'; @@ -60,19 +62,71 @@ class RowService { } } +class RowsNotifier extends ChangeNotifier { + List _rows = []; + GridRowChangeReason _changeReason = const InitialListState(); + + void updateRows(List rows, GridRowChangeReason changeReason) { + _rows = rows; + _changeReason = changeReason; + + changeReason.map( + insert: (_) => notifyListeners(), + delete: (_) => notifyListeners(), + update: (_) => notifyListeners(), + initial: (_) {}, + ); + } + + List get rows => _rows; +} + class GridRowCache { final String gridId; + late GridRowListener _rowsListener; + final HashMap _rowDataMap = HashMap(); + UnmodifiableListView _fields = UnmodifiableListView([]); - HashMap rowDataMap = HashMap(); + final RowsNotifier _rowNotifier = RowsNotifier(); - List _rows = []; + GridRowCache({required this.gridId}) { + _rowsListener = GridRowListener(gridId: gridId); + _rowsListener.rowsUpdateNotifier.addPublishListener((result) { + result.fold( + (changesets) { + for (final changeset in changesets) { + _deleteRows(changeset.deletedRows); + _insertRows(changeset.insertedRows); + _updateRows(changeset.updatedRows); + } + }, + (err) => Log.error(err), + ); + }); + _rowsListener.start(); + } - GridRowCache({required this.gridId}); + List get clonedRows => [..._rowNotifier.rows]; - List get rows => [..._rows]; + Future dispose() async { + await _rowsListener.stop(); + _rowNotifier.dispose(); + } + + void addListener({void Function(List, GridRowChangeReason)? onChanged, bool Function()? listenWhen}) { + _rowNotifier.addListener(() { + if (listenWhen != null && listenWhen() == false) { + return; + } + + if (onChanged != null) { + onChanged(clonedRows, _rowNotifier._changeReason); + } + }); + } Future> getRowData(String rowId) async { - final Row? data = rowDataMap[rowId]; + final Row? data = _rowDataMap[rowId]; if (data != null) { return Future(() => Some(data)); } @@ -86,7 +140,7 @@ class GridRowCache { return result.fold( (data) { data.freeze(); - rowDataMap[data.id] = data; + _rowDataMap[data.id] = data; return Some(data); }, (err) { @@ -99,73 +153,65 @@ class GridRowCache { void updateWithBlock(List blocks, UnmodifiableListView fields) { _fields = fields; - _rows = blocks.expand((block) => block.rowOrders).map((rowOrder) { + final newRows = blocks.expand((block) => block.rowOrders).map((rowOrder) { return GridRow.fromBlockRow(gridId, rowOrder, _fields); }).toList(); + + _rowNotifier.updateRows(newRows, const GridRowChangeReason.initial()); } - void updateFields(UnmodifiableListView fields) { - if (fields.isEmpty) { - return; - } - - _fields = fields; - _rows = _rows.map((row) => row.copyWith(fields: fields)).toList(); - } - - Option deleteRows(List deletedRows) { + void _deleteRows(List deletedRows) { if (deletedRows.isEmpty) { - return none(); + return; } final List newRows = []; final DeletedIndex deletedIndex = []; final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; - _rows.asMap().forEach((index, value) { + + _rowNotifier.rows.asMap().forEach((index, value) { if (deletedRowMap[value.rowId] == null) { newRows.add(value); } else { deletedIndex.add(Tuple2(index, value)); } }); - _rows = newRows; - return Some(GridListState.delete(deletedIndex)); + _rowNotifier.updateRows(newRows, GridRowChangeReason.delete(deletedIndex)); } - Option insertRows(List createdRows) { + void _insertRows(List createdRows) { if (createdRows.isEmpty) { - return none(); + return; } InsertedIndexs insertIndexs = []; + final List newRows = _rowNotifier.rows; for (final createdRow in createdRows) { final gridRow = GridRow.fromBlockRow(gridId, createdRow.rowOrder, _fields); insertIndexs.add(Tuple2(createdRow.index, gridRow.rowId)); - _rows.insert(createdRow.index, gridRow); + newRows.insert(createdRow.index, gridRow); } - - return Some(GridListState.insert(insertIndexs)); + _rowNotifier.updateRows(newRows, GridRowChangeReason.insert(insertIndexs)); } - void updateRows(List updatedRows) { + void _updateRows(List updatedRows) { if (updatedRows.isEmpty) { return; } final List updatedIndexs = []; - for (final updatedRow in updatedRows) { - final index = _rows.indexWhere((row) => row.rowId == updatedRow.rowId); + final List newRows = _rowNotifier.rows; + for (final rowOrder in updatedRows) { + final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); if (index != -1) { - _rows.removeAt(index); - _rows.insert(index, _toRowData(updatedRow)); + newRows.removeAt(index); + newRows.insert(index, GridRow.fromBlockRow(gridId, rowOrder, _fields)); updatedIndexs.add(index); } } - } - GridRow _toRowData(RowOrder rowOrder) { - return GridRow.fromBlockRow(gridId, rowOrder, _fields); + _rowNotifier.updateRows(newRows, GridRowChangeReason.update(updatedIndexs)); } } @@ -204,8 +250,9 @@ typedef InsertedIndexs = List>; typedef DeletedIndex = List>; @freezed -class GridListState with _$GridListState { - const factory GridListState.insert(InsertedIndexs items) = _Insert; - const factory GridListState.delete(DeletedIndex items) = _Delete; - const factory GridListState.initial() = InitialListState; +class GridRowChangeReason with _$GridRowChangeReason { + const factory GridRowChangeReason.insert(InsertedIndexs items) = _Insert; + const factory GridRowChangeReason.delete(DeletedIndex items) = _Delete; + const factory GridRowChangeReason.update(List indexs) = _Update; + const factory GridRowChangeReason.initial() = InitialListState; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index 634bb1e56d..bf87851ebb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -1,5 +1,4 @@ import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; -import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; @@ -11,13 +10,11 @@ part 'property_bloc.freezed.dart'; class GridPropertyBloc extends Bloc { final FieldService _service; - final GridFieldsListener _fieldListener; final GridFieldCache _fieldCache; GridPropertyBloc({required String gridId, required List fields}) : _service = FieldService(gridId: gridId), - _fieldListener = GridFieldsListener(gridId: gridId), - _fieldCache = GridFieldCache(), + _fieldCache = GridFieldCache(gridId: gridId), super(GridPropertyState.initial(gridId, fields)) { on( (event, emit) async { @@ -45,22 +42,15 @@ class GridPropertyBloc extends Bloc { @override Future close() async { - await _fieldListener.stop(); - _fieldCache.dispose(); + await _fieldCache.dispose(); return super.close(); } void _startListening() { - _fieldListener.updateFieldsNotifier?.addPublishListener((result) { - result.fold( - (changeset) { - _fieldCache.applyChangeset(changeset); - add(GridPropertyEvent.didReceiveFieldUpdate(_fieldCache.clonedFields)); - }, - (err) => Log.error(err), - ); - }); - _fieldListener.start(); + _fieldCache.addListener( + onChanged: (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(_fieldCache.clonedFields)), + listenWhen: () => !isClosed, + ); } } 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 1acdf5db2f..1a5f64c03a 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 @@ -205,7 +205,8 @@ class _GridRowsState extends State<_GridRows> { ); } }, - initial: (updatedIndexs) {}, + initial: (_) {}, + update: (_) {}, ); }, buildWhen: (previous, current) => false, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index 22bd59eb4d..63a397710c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -5,7 +5,6 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 6a22c88ca5..7f704991b7 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -1,4 +1,3 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart'; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index 2cf56fd5f0..f40b93233e 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -215,7 +215,7 @@ impl GridMetaPad { |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) { None => Ok(None), Some(index) => { - debug_assert_eq!(index, from_index); + // debug_assert_eq!(index, from_index); let field_meta = grid_meta.fields.remove(index); grid_meta.fields.insert(to_index, field_meta); Ok(Some(())) From e647fd0a5749c5b408760f7e19efd9ffff24d630 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 17 Apr 2022 08:04:29 +0800 Subject: [PATCH 166/179] chore: add cell cache --- .../app_flowy/lib/startup/deps_resolver.dart | 12 +-- .../{cell_bloc => cell}/cell_listener.dart | 0 .../application/grid/cell/cell_service.dart | 75 +++++++++++++++++++ .../checkbox_cell_bloc.dart | 8 +- .../{cell_bloc => cell}/date_cell_bloc.dart | 14 ++-- .../{cell_bloc => cell}/number_cell_bloc.dart | 8 +- .../select_option_service.dart | 0 .../selection_cell_bloc.dart | 10 +-- .../selection_editor_bloc.dart | 6 +- .../{cell_bloc => cell}/text_cell_bloc.dart | 8 +- .../grid/cell_bloc/cell_service.dart | 35 --------- .../workspace/application/grid/prelude.dart | 12 +-- .../application/grid/row/row_bloc.dart | 4 +- .../application/grid/row/row_service.dart | 6 +- .../grid/src/widgets/cell/cell_builder.dart | 2 +- .../grid/src/widgets/cell/checkbox_cell.dart | 2 +- .../grid/src/widgets/cell/date_cell.dart | 2 +- .../grid/src/widgets/cell/number_cell.dart | 2 +- .../cell/selection_cell/selection_cell.dart | 4 +- .../cell/selection_cell/selection_editor.dart | 6 +- .../grid/src/widgets/cell/text_cell.dart | 2 +- .../src/widgets/row/cell/number_cell.dart | 2 +- .../grid/src/widgets/row/number_cell.dart | 2 +- 23 files changed, 131 insertions(+), 91 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/cell_listener.dart (100%) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/checkbox_cell_bloc.dart (92%) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/date_cell_bloc.dart (87%) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/number_cell_bloc.dart (93%) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/select_option_service.dart (100%) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/selection_cell_bloc.dart (89%) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/selection_editor_bloc.dart (97%) rename frontend/app_flowy/lib/workspace/application/grid/{cell_bloc => cell}/text_cell_bloc.dart (86%) delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 47267cc2c9..7e26566367 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -171,32 +171,32 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => TextCellBloc( service: CellService(), cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => SelectionCellBloc( cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => NumberCellBloc( cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => DateCellBloc( - cellData: cellData, + cellIdentifier: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => CheckboxCellBloc( service: CellService(), cellData: cellData, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_listener.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart new file mode 100644 index 0000000000..a4a3cf2d60 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart @@ -0,0 +1,75 @@ +import 'dart:collection'; + +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; + +class CellService { + CellService(); + + Future> updateCell({ + required String gridId, + required String fieldId, + required String rowId, + required String data, + }) { + final payload = CellChangeset.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..data = data; + return GridEventUpdateCell(payload).send(); + } + + Future> getCell({ + required String gridId, + required String fieldId, + required String rowId, + }) { + final payload = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + return GridEventGetCell(payload).send(); + } +} + +class CellCache { + final CellService _cellService; + final HashMap _cellDataMap = HashMap(); + + CellCache() : _cellService = CellService(); + + Future> getCellData(GridCellIdentifier identifier) async { + final cellId = _cellId(identifier); + final Cell? data = _cellDataMap[cellId]; + if (data != null) { + return Future(() => Some(data)); + } + + final result = await _cellService.getCell( + gridId: identifier.gridId, + fieldId: identifier.field.id, + rowId: identifier.rowId, + ); + + return result.fold( + (cell) { + _cellDataMap[_cellId(identifier)] = cell; + return Some(cell); + }, + (err) { + Log.error(err); + return none(); + }, + ); + } + + String _cellId(GridCellIdentifier identifier) { + return "${identifier.rowId}/${identifier.field.id}"; + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart similarity index 92% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart index 3a4500eb45..2fae2464be 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; @@ -15,7 +15,7 @@ class CheckboxCellBloc extends Bloc { CheckboxCellBloc({ required CellService service, - required CellData cellData, + required GridCellIdentifier cellData, }) : _service = service, _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(CheckboxCellState.initial(cellData)) { @@ -87,11 +87,11 @@ class CheckboxCellEvent with _$CheckboxCellEvent { @freezed class CheckboxCellState with _$CheckboxCellState { const factory CheckboxCellState({ - required CellData cellData, + required GridCellIdentifier cellData, required bool isSelected, }) = _CheckboxCellState; - factory CheckboxCellState.initial(CellData cellData) { + factory CheckboxCellState.initial(GridCellIdentifier cellData) { return CheckboxCellState(cellData: cellData, isSelected: _isSelected(cellData.cell)); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart similarity index 87% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart index d7e0c078aa..e4c94230a9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; @@ -15,11 +15,11 @@ class DateCellBloc extends Bloc { final CellListener _cellListener; final SingleFieldListener _fieldListener; - DateCellBloc({required CellData cellData}) + DateCellBloc({required GridCellIdentifier cellIdentifier}) : _service = CellService(), - _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), - _fieldListener = SingleFieldListener(fieldId: cellData.field.id), - super(DateCellState.initial(cellData)) { + _cellListener = CellListener(rowId: cellIdentifier.rowId, fieldId: cellIdentifier.field.id), + _fieldListener = SingleFieldListener(fieldId: cellIdentifier.field.id), + super(DateCellState.initial(cellIdentifier)) { on( (event, emit) async { event.map( @@ -106,13 +106,13 @@ class DateCellEvent with _$DateCellEvent { @freezed class DateCellState with _$DateCellState { const factory DateCellState({ - required CellData cellData, + required GridCellIdentifier cellData, required String content, required Field field, DateTime? selectedDay, }) = _DateCellState; - factory DateCellState.initial(CellData cellData) => DateCellState( + factory DateCellState.initial(GridCellIdentifier cellData) => DateCellState( cellData: cellData, field: cellData.field, content: cellData.cell?.content ?? "", diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart index fbc432c557..531e06062a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; @@ -16,7 +16,7 @@ class NumberCellBloc extends Bloc { final SingleFieldListener _fieldListener; NumberCellBloc({ - required CellData cellData, + required GridCellIdentifier cellData, }) : _service = CellService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), _fieldListener = SingleFieldListener(fieldId: cellData.field.id), @@ -105,11 +105,11 @@ class NumberCellEvent with _$NumberCellEvent { @freezed class NumberCellState with _$NumberCellState { const factory NumberCellState({ - required CellData cellData, + required GridCellIdentifier cellData, required String content, }) = _NumberCellState; - factory NumberCellState.initial(CellData cellData) { + factory NumberCellState.initial(GridCellIdentifier cellData) { return NumberCellState(cellData: cellData, content: cellData.cell?.content ?? ""); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart similarity index 89% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart index ae7c48d81f..95ccedd086 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart @@ -1,5 +1,5 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/select_option_service.dart'; +import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart'; import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; @@ -16,7 +16,7 @@ class SelectionCellBloc extends Bloc { final SingleFieldListener _fieldListener; SelectionCellBloc({ - required CellData cellData, + required GridCellIdentifier cellData, }) : _service = SelectOptionService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), _fieldListener = SingleFieldListener(fieldId: cellData.field.id), @@ -93,12 +93,12 @@ class SelectionCellEvent with _$SelectionCellEvent { @freezed class SelectionCellState with _$SelectionCellState { const factory SelectionCellState({ - required CellData cellData, + required GridCellIdentifier cellData, required List options, required List selectedOptions, }) = _SelectionCellState; - factory SelectionCellState.initial(CellData cellData) => SelectionCellState( + factory SelectionCellState.initial(GridCellIdentifier cellData) => SelectionCellState( cellData: cellData, options: [], selectedOptions: [], diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart similarity index 97% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart index 0d1b2705e3..1636c293ed 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; +import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/field/field_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/log.dart'; @@ -18,7 +18,7 @@ class SelectOptionEditorBloc extends Bloc options, required List selectedOptions, }) : _selectOptionService = SelectOptionService(), @@ -174,7 +174,7 @@ class SelectOptionEditorState with _$SelectOptionEditorState { }) = _SelectOptionEditorState; factory SelectOptionEditorState.initial( - CellData cellData, + GridCellIdentifier cellData, List options, List selectedOptions, ) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart similarity index 86% rename from frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart index 5af39bbd9f..e45cb7c1f1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart @@ -11,7 +11,7 @@ class TextCellBloc extends Bloc { TextCellBloc({ required this.service, - required CellData cellData, + required GridCellIdentifier cellData, }) : super(TextCellState.initial(cellData)) { on( (event, emit) async { @@ -53,7 +53,7 @@ class TextCellBloc extends Bloc { @freezed class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; - const factory TextCellEvent.didReceiveCellData(CellData cellData) = _DidReceiveCellData; + const factory TextCellEvent.didReceiveCellData(GridCellIdentifier cellData) = _DidReceiveCellData; const factory TextCellEvent.updateText(String text) = _UpdateText; } @@ -61,10 +61,10 @@ class TextCellEvent with _$TextCellEvent { class TextCellState with _$TextCellState { const factory TextCellState({ required String content, - required CellData cellData, + required GridCellIdentifier cellData, }) = _TextCellState; - factory TextCellState.initial(CellData cellData) => TextCellState( + factory TextCellState.initial(GridCellIdentifier cellData) => TextCellState( content: cellData.cell?.content ?? "", cellData: cellData, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart deleted file mode 100644 index dfce5d3993..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; - -class CellService { - CellService(); - - Future> updateCell({ - required String gridId, - required String fieldId, - required String rowId, - required String data, - }) { - final payload = CellChangeset.create() - ..gridId = gridId - ..fieldId = fieldId - ..rowId = rowId - ..data = data; - return GridEventUpdateCell(payload).send(); - } - - Future> getCell({ - required String gridId, - required String fieldId, - required String rowId, - }) { - final payload = CellIdentifierPayload.create() - ..gridId = gridId - ..fieldId = fieldId - ..rowId = rowId; - return GridEventGetCell(payload).send(); - } -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 1308e1a67e..16287db6bf 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -16,12 +16,12 @@ export 'field/type_option/number_bloc.dart'; export 'field/type_option/single_select_bloc.dart'; // Cell -export 'cell_bloc/text_cell_bloc.dart'; -export 'cell_bloc/number_cell_bloc.dart'; -export 'cell_bloc/selection_cell_bloc.dart'; -export 'cell_bloc/date_cell_bloc.dart'; -export 'cell_bloc/checkbox_cell_bloc.dart'; -export 'cell_bloc/cell_service.dart'; +export 'cell/text_cell_bloc.dart'; +export 'cell/number_cell_bloc.dart'; +export 'cell/selection_cell_bloc.dart'; +export 'cell/date_cell_bloc.dart'; +export 'cell/checkbox_cell_bloc.dart'; +export 'cell/cell_service.dart'; // Setting export 'setting/setting_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 4ec7ce3a17..69731a0329 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -12,7 +12,7 @@ import 'package:dartz/dartz.dart'; part 'row_bloc.freezed.dart'; -typedef CellDataMap = LinkedHashMap; +typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { final RowService _rowService; @@ -111,7 +111,7 @@ class RowBloc extends Bloc { var map = CellDataMap.new(); for (final field in fields) { if (field.visibility) { - map[field.id] = CellData( + map[field.id] = GridCellIdentifier( rowId: row.id, gridId: _rowService.gridId, cell: row.cellByFieldId[field.id], diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 23cecb1489..c35466f5c3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -84,10 +84,10 @@ class RowsNotifier extends ChangeNotifier { class GridRowCache { final String gridId; late GridRowListener _rowsListener; + final RowsNotifier _rowNotifier = RowsNotifier(); final HashMap _rowDataMap = HashMap(); UnmodifiableListView _fields = UnmodifiableListView([]); - final RowsNotifier _rowNotifier = RowsNotifier(); GridRowCache({required this.gridId}) { _rowsListener = GridRowListener(gridId: gridId); @@ -216,8 +216,8 @@ class GridRowCache { } @freezed -class CellData with _$CellData { - const factory CellData({ +class GridCellIdentifier with _$GridCellIdentifier { + const factory GridCellIdentifier({ required String gridId, required String rowId, required Field field, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 2b00a13a10..7af09ca6b5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -7,7 +7,7 @@ import 'number_cell.dart'; import 'selection_cell/selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(CellData cellData) { +Widget buildGridCell(GridCellIdentifier cellData) { final key = ValueKey(cellData.field.id + cellData.rowId); switch (cellData.field.fieldType) { case FieldType.Checkbox: diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index b4095c71d9..312c8ef71c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final CellData cellData; + final GridCellIdentifier cellData; const CheckboxCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index b913a09e4e..33f99c2386 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -9,7 +9,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:table_calendar/table_calendar.dart'; class DateCell extends GridCell { - final CellData cellData; + final GridCellIdentifier cellData; const DateCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index cd4db24c7a..56946945ae 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends GridCell { - final CellData cellData; + final GridCellIdentifier cellData; const NumberCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index a7cf70a64e..4e0cba65bb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -8,7 +8,7 @@ import 'extension.dart'; import 'selection_editor.dart'; class SingleSelectCell extends GridCell { - final CellData cellData; + final GridCellIdentifier cellData; const SingleSelectCell({ required this.cellData, @@ -64,7 +64,7 @@ class _SingleSelectCellState extends State { //---------------------------------------------------------------- class MultiSelectCell extends GridCell { - final CellData cellData; + final GridCellIdentifier cellData; const MultiSelectCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 4ebd4407b0..e3e0b39f0a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -1,5 +1,5 @@ import 'dart:collection'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/cell/selection_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart'; @@ -25,7 +25,7 @@ import 'text_field.dart'; const double _editorPannelWidth = 300; class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { - final CellData cellData; + final GridCellIdentifier cellData; final List options; final List selectedOptions; final VoidCallback onDismissed; @@ -66,7 +66,7 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { static void show( BuildContext context, - CellData cellData, + GridCellIdentifier cellData, List options, List selectedOptions, VoidCallback onDismissed, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index 543a337b9b..e6649853a5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -6,7 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_container.dart'; class GridTextCell extends GridCell { - final CellData cellData; + final GridCellIdentifier cellData; const GridTextCell({ required this.cellData, Key? key, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart index 41b8cf6ee5..6e4c430986 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final CellData cellData; + final GridCellIdentifier cellData; const NumberCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart index 41b8cf6ee5..6e4c430986 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final CellData cellData; + final GridCellIdentifier cellData; const NumberCell({ required this.cellData, From 0a19364ea7b6af05c458e095cd40cd7670a70df3 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 17 Apr 2022 09:46:38 +0800 Subject: [PATCH 167/179] chore: remove row listener from rowbloc --- .../workspace/application/grid/grid_bloc.dart | 1 - .../application/grid/grid_listener.dart | 2 +- .../application/grid/row/row_bloc.dart | 23 ++--- .../application/grid/row/row_service.dart | 95 +++++++++++++++---- .../plugins/grid/src/grid_page.dart | 10 +- .../flowy-grid/dart_notification.pbenum.dart | 12 +-- .../flowy-grid/dart_notification.pbjson.dart | 10 +- .../flowy-grid/src/dart_notification.rs | 8 +- .../src/protobuf/model/dart_notification.rs | 30 +++--- .../protobuf/proto/dart_notification.proto | 8 +- .../src/services/block_meta_manager.rs | 65 +++++-------- .../flowy-grid/src/services/grid_editor.rs | 16 ++-- .../src/client_grid/grid_meta_pad.rs | 2 +- 13 files changed, 158 insertions(+), 124 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 4d54081980..f38e874453 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -46,7 +46,6 @@ class GridBloc extends Bloc { await _gridService.closeGrid(); await fieldCache.dispose(); await rowCache.dispose(); - fieldCache.dispose(); return super.close(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index fcff6fa15f..e6c7dc9de7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -23,7 +23,7 @@ class GridRowListener { void _handler(GridNotification ty, Either result) { switch (ty) { - case GridNotification.DidUpdateGridBlock: + case GridNotification.DidUpdateGridRow: result.fold( (payload) => rowsUpdateNotifier.value = left([GridRowsChangeset.fromBuffer(payload)]), (error) => rowsUpdateNotifier.value = right(error), diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 69731a0329..1f026a0af6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,12 +1,9 @@ import 'dart:collection'; - import 'package:app_flowy/workspace/application/grid/grid_service.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'row_listener.dart'; import 'row_service.dart'; import 'package:dartz/dartz.dart'; @@ -16,7 +13,7 @@ typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { final RowService _rowService; - final RowListener _rowlistener; + final GridFieldCache _fieldCache; final GridRowCache _rowCache; @@ -25,7 +22,6 @@ class RowBloc extends Bloc { required GridFieldCache fieldCache, required GridRowCache rowCache, }) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), - _rowlistener = RowListener(rowId: rowData.rowId), _fieldCache = fieldCache, _rowCache = rowCache, super(RowState.initial(rowData)) { @@ -76,27 +72,20 @@ class RowBloc extends Bloc { @override Future close() async { - await _rowlistener.stop(); return super.close(); } Future _startListening() async { - _rowlistener.updateRowNotifier?.addPublishListener( - (result) { - result.fold( - (row) => add(RowEvent.didUpdateRow(row)), - (err) => Log.error(err), - ); - }, - listenWhen: () => !isClosed, - ); - _fieldCache.addListener( listener: () => add(const RowEvent.fieldsDidUpdate()), listenWhen: () => !isClosed, ); - _rowlistener.start(); + _rowCache.addRowListener( + rowId: state.rowData.rowId, + onUpdated: (row) => add(RowEvent.didUpdateRow(row)), + listenWhen: () => !isClosed, + ); } Future _loadRow(Emitter emit) async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index c35466f5c3..bed21d1691 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,6 +1,5 @@ import 'dart:collection'; -import 'package:app_flowy/workspace/application/grid/grid_listener.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; @@ -10,6 +9,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:app_flowy/workspace/application/grid/grid_listener.dart'; + part 'row_service.freezed.dart'; class RowService { @@ -86,7 +87,6 @@ class GridRowCache { late GridRowListener _rowsListener; final RowsNotifier _rowNotifier = RowsNotifier(); final HashMap _rowDataMap = HashMap(); - UnmodifiableListView _fields = UnmodifiableListView([]); GridRowCache({required this.gridId}) { @@ -113,8 +113,11 @@ class GridRowCache { _rowNotifier.dispose(); } - void addListener({void Function(List, GridRowChangeReason)? onChanged, bool Function()? listenWhen}) { - _rowNotifier.addListener(() { + void addListener({ + void Function(List, GridRowChangeReason)? onChanged, + bool Function()? listenWhen, + }) { + listener() { if (listenWhen != null && listenWhen() == false) { return; } @@ -122,6 +125,32 @@ class GridRowCache { if (onChanged != null) { onChanged(clonedRows, _rowNotifier._changeReason); } + } + + _rowNotifier.addListener(listener); + } + + void addRowListener({ + required String rowId, + void Function(Row)? onUpdated, + bool Function()? listenWhen, + }) { + _rowNotifier.addListener(() { + if (onUpdated == null) { + return; + } + + if (listenWhen != null && listenWhen() == false) { + return; + } + + _rowNotifier._changeReason.whenOrNull(update: (indexs) { + final updatedIndex = indexs.firstWhereOrNull((updatedIndex) => updatedIndex.rowId == rowId); + final row = _rowDataMap[rowId]; + if (updatedIndex != null && row != null) { + onUpdated(row); + } + }); }); } @@ -166,14 +195,14 @@ class GridRowCache { } final List newRows = []; - final DeletedIndex deletedIndex = []; + final DeletedIndexs deletedIndex = []; final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; - _rowNotifier.rows.asMap().forEach((index, value) { - if (deletedRowMap[value.rowId] == null) { - newRows.add(value); + _rowNotifier.rows.asMap().forEach((index, row) { + if (deletedRowMap[row.rowId] == null) { + newRows.add(row); } else { - deletedIndex.add(Tuple2(index, value)); + deletedIndex.add(DeletedIndex(index: index, row: row)); } }); @@ -189,7 +218,12 @@ class GridRowCache { final List newRows = _rowNotifier.rows; for (final createdRow in createdRows) { final gridRow = GridRow.fromBlockRow(gridId, createdRow.rowOrder, _fields); - insertIndexs.add(Tuple2(createdRow.index, gridRow.rowId)); + insertIndexs.add( + InsertedIndex( + index: createdRow.index, + rowId: gridRow.rowId, + ), + ); newRows.insert(createdRow.index, gridRow); } _rowNotifier.updateRows(newRows, GridRowChangeReason.insert(insertIndexs)); @@ -200,14 +234,15 @@ class GridRowCache { return; } - final List updatedIndexs = []; + final UpdatedIndexs updatedIndexs = []; final List newRows = _rowNotifier.rows; for (final rowOrder in updatedRows) { final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); if (index != -1) { newRows.removeAt(index); newRows.insert(index, GridRow.fromBlockRow(gridId, rowOrder, _fields)); - updatedIndexs.add(index); + _rowDataMap.remove(rowOrder.rowId); + updatedIndexs.add(UpdatedIndex(index: index, rowId: rowOrder.rowId)); } } @@ -246,13 +281,41 @@ class GridRow with _$GridRow { } } -typedef InsertedIndexs = List>; -typedef DeletedIndex = List>; +typedef InsertedIndexs = List; +typedef DeletedIndexs = List; +typedef UpdatedIndexs = List; + +class InsertedIndex { + int index; + String rowId; + InsertedIndex({ + required this.index, + required this.rowId, + }); +} + +class DeletedIndex { + int index; + GridRow row; + DeletedIndex({ + required this.index, + required this.row, + }); +} + +class UpdatedIndex { + int index; + String rowId; + UpdatedIndex({ + required this.index, + required this.rowId, + }); +} @freezed class GridRowChangeReason with _$GridRowChangeReason { const factory GridRowChangeReason.insert(InsertedIndexs items) = _Insert; - const factory GridRowChangeReason.delete(DeletedIndex items) = _Delete; - const factory GridRowChangeReason.update(List indexs) = _Update; + const factory GridRowChangeReason.delete(DeletedIndexs items) = _Delete; + const factory GridRowChangeReason.update(UpdatedIndexs indexs) = _Update; const factory GridRowChangeReason.initial() = InitialListState; } 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 1a5f64c03a..c4b937300e 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 @@ -191,22 +191,20 @@ class _GridRowsState extends State<_GridRows> { return BlocConsumer( listenWhen: (previous, current) => previous.listState != current.listState, listener: (context, state) { - state.listState.map( + state.listState.mapOrNull( insert: (value) { for (final item in value.items) { - _key.currentState?.insertItem(item.value1); + _key.currentState?.insertItem(item.index); } }, delete: (value) { for (final item in value.items) { _key.currentState?.removeItem( - item.value1, - (context, animation) => _renderRow(context, item.value2, animation), + item.index, + (context, animation) => _renderRow(context, item.row, animation), ); } }, - initial: (_) {}, - update: (_) {}, ); }, buildWhen: (previous, current) => false, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 7b43def65e..7a89d33361 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -12,19 +12,19 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock'); - static const GridNotification DidUpdateGridBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridBlock'); + static const GridNotification DidUpdateGridRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridRow'); + static const GridNotification DidUpdateGridField = GridNotification._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridField'); static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow'); - static const GridNotification DidUpdateCell = GridNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateCell'); - static const GridNotification DidUpdateGridField = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateGridField'); - static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); + static const GridNotification DidUpdateCell = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateCell'); + static const GridNotification DidUpdateField = GridNotification._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField'); static const $core.List values = [ Unknown, DidCreateBlock, - DidUpdateGridBlock, + DidUpdateGridRow, + DidUpdateGridField, DidUpdateRow, DidUpdateCell, - DidUpdateGridField, DidUpdateField, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 8c262092db..96a087ca40 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -14,13 +14,13 @@ const GridNotification$json = const { '2': const [ const {'1': 'Unknown', '2': 0}, const {'1': 'DidCreateBlock', '2': 11}, - const {'1': 'DidUpdateGridBlock', '2': 20}, + const {'1': 'DidUpdateGridRow', '2': 20}, + const {'1': 'DidUpdateGridField', '2': 21}, const {'1': 'DidUpdateRow', '2': 30}, - const {'1': 'DidUpdateCell', '2': 31}, - const {'1': 'DidUpdateGridField', '2': 40}, - const {'1': 'DidUpdateField', '2': 41}, + const {'1': 'DidUpdateCell', '2': 40}, + const {'1': 'DidUpdateField', '2': 50}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhYKEkRpZFVwZGF0ZUdyaWRCbG9jaxAUEhAKDERpZFVwZGF0ZVJvdxAeEhEKDURpZFVwZGF0ZUNlbGwQHxIWChJEaWRVcGRhdGVHcmlkRmllbGQQKBISCg5EaWRVcGRhdGVGaWVsZBAp'); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhQKEERpZFVwZGF0ZUdyaWRSb3cQFBIWChJEaWRVcGRhdGVHcmlkRmllbGQQFRIQCgxEaWRVcGRhdGVSb3cQHhIRCg1EaWRVcGRhdGVDZWxsECgSEgoORGlkVXBkYXRlRmllbGQQMg=='); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index 156ba9058a..92749da519 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -6,11 +6,11 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; pub enum GridNotification { Unknown = 0, DidCreateBlock = 11, - DidUpdateGridBlock = 20, + DidUpdateGridRow = 20, + DidUpdateGridField = 21, DidUpdateRow = 30, - DidUpdateCell = 31, - DidUpdateGridField = 40, - DidUpdateField = 41, + DidUpdateCell = 40, + DidUpdateField = 50, } impl std::default::Default for GridNotification { diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 338737c643..ff60cbf9e7 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -27,11 +27,11 @@ pub enum GridNotification { Unknown = 0, DidCreateBlock = 11, - DidUpdateGridBlock = 20, + DidUpdateGridRow = 20, + DidUpdateGridField = 21, DidUpdateRow = 30, - DidUpdateCell = 31, - DidUpdateGridField = 40, - DidUpdateField = 41, + DidUpdateCell = 40, + DidUpdateField = 50, } impl ::protobuf::ProtobufEnum for GridNotification { @@ -43,11 +43,11 @@ impl ::protobuf::ProtobufEnum for GridNotification { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), 11 => ::std::option::Option::Some(GridNotification::DidCreateBlock), - 20 => ::std::option::Option::Some(GridNotification::DidUpdateGridBlock), + 20 => ::std::option::Option::Some(GridNotification::DidUpdateGridRow), + 21 => ::std::option::Option::Some(GridNotification::DidUpdateGridField), 30 => ::std::option::Option::Some(GridNotification::DidUpdateRow), - 31 => ::std::option::Option::Some(GridNotification::DidUpdateCell), - 40 => ::std::option::Option::Some(GridNotification::DidUpdateGridField), - 41 => ::std::option::Option::Some(GridNotification::DidUpdateField), + 40 => ::std::option::Option::Some(GridNotification::DidUpdateCell), + 50 => ::std::option::Option::Some(GridNotification::DidUpdateField), _ => ::std::option::Option::None } } @@ -56,10 +56,10 @@ impl ::protobuf::ProtobufEnum for GridNotification { static values: &'static [GridNotification] = &[ GridNotification::Unknown, GridNotification::DidCreateBlock, - GridNotification::DidUpdateGridBlock, + GridNotification::DidUpdateGridRow, + GridNotification::DidUpdateGridField, GridNotification::DidUpdateRow, GridNotification::DidUpdateCell, - GridNotification::DidUpdateGridField, GridNotification::DidUpdateField, ]; values @@ -89,11 +89,11 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x9c\x01\n\x10GridNotification\x12\x0b\n\ - \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x16\n\x12DidUp\ - dateGridBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUp\ - dateCell\x10\x1f\x12\x16\n\x12DidUpdateGridField\x10(\x12\x12\n\x0eDidUp\ - dateField\x10)b\x06proto3\ + \n\x17dart_notification.proto*\x9a\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x14\n\x10DidUp\ + dateGridRow\x10\x14\x12\x16\n\x12DidUpdateGridField\x10\x15\x12\x10\n\ + \x0cDidUpdateRow\x10\x1e\x12\x11\n\rDidUpdateCell\x10(\x12\x12\n\x0eDidU\ + pdateField\x102b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index a4e5188346..9a2899833f 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -3,9 +3,9 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; DidCreateBlock = 11; - DidUpdateGridBlock = 20; + DidUpdateGridRow = 20; + DidUpdateGridField = 21; DidUpdateRow = 30; - DidUpdateCell = 31; - DidUpdateGridField = 40; - DidUpdateField = 41; + DidUpdateCell = 40; + DidUpdateField = 50; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 2a8eae4497..58c623adc6 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -2,13 +2,13 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::ClientGridBlockMetaEditor; use crate::services::persistence::block_index::BlockIndexPersistence; -use crate::services::row::{group_row_orders, make_rows_from_row_metas, GridBlockSnapshot}; +use crate::services::row::{group_row_orders, GridBlockSnapshot}; use std::borrow::Cow; use dashmap::DashMap; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - CellChangeset, CellMeta, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridRowsChangeset, + CellChangeset, CellMeta, CellNotificationData, GridBlockMeta, GridBlockMetaChangeset, GridRowsChangeset, IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -76,7 +76,7 @@ impl GridBlockMetaEditorManager { index_row_order.index = row_index; let _ = self - .notify_did_update_rows(GridRowsChangeset::insert(block_id, vec![index_row_order])) + .notify_did_update_block(GridRowsChangeset::insert(block_id, vec![index_row_order])) .await?; Ok(row_count) } @@ -98,7 +98,7 @@ impl GridBlockMetaEditorManager { changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); let _ = self - .notify_did_update_rows(GridRowsChangeset::insert(&block_id, inserted_row_orders)) + .notify_did_update_block(GridRowsChangeset::insert(&block_id, inserted_row_orders)) .await?; } @@ -108,19 +108,7 @@ impl GridBlockMetaEditorManager { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - - match editor - .get_row_orders(Some(vec![Cow::Borrowed(&changeset.row_id)])) - .await? - .pop() - { - None => {} - Some(row_order) => { - let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); - let _ = self.notify_did_update_rows(block_order_changeset).await?; - } - } - + let _ = self.notify_did_update_block_row(&changeset.row_id).await?; Ok(()) } @@ -131,7 +119,7 @@ impl GridBlockMetaEditorManager { let row_orders = editor.get_row_orders(Some(vec![Cow::Borrowed(&row_id)])).await?; let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?; let _ = self - .notify_did_update_rows(GridRowsChangeset::delete(&block_id, row_orders)) + .notify_did_update_block(GridRowsChangeset::delete(&block_id, row_orders)) .await?; Ok(()) @@ -173,7 +161,7 @@ impl GridBlockMetaEditorManager { updated_rows: vec![], }; - let _ = self.notify_did_update_rows(notified_changeset).await?; + let _ = self.notify_did_update_block(notified_changeset).await?; } } @@ -181,10 +169,8 @@ impl GridBlockMetaEditorManager { } pub async fn update_cell(&self, changeset: CellChangeset) -> FlowyResult<()> { - let row_id = changeset.row_id.clone(); - let editor = self.get_editor_from_row_id(&row_id).await?; let row_changeset: RowMetaChangeset = changeset.clone().into(); - let _ = editor.update_row(row_changeset).await?; + let _ = self.update_row(row_changeset).await?; let cell_notification_data = CellNotificationData { grid_id: changeset.grid_id, @@ -193,6 +179,7 @@ impl GridBlockMetaEditorManager { content: changeset.data, }; self.notify_did_update_cell(cell_notification_data).await?; + Ok(()) } @@ -239,8 +226,22 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn notify_did_update_rows(&self, changeset: GridRowsChangeset) -> FlowyResult<()> { - send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock) + async fn notify_did_update_block_row(&self, row_id: &str) -> FlowyResult<()> { + let editor = self.get_editor_from_row_id(row_id).await?; + let row_ids = Some(vec![Cow::Borrowed(&row_id)]); + match editor.get_row_orders(row_ids).await?.pop() { + None => {} + Some(row_order) => { + let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); + let _ = self.notify_did_update_block(block_order_changeset).await?; + } + } + + Ok(()) + } + + async fn notify_did_update_block(&self, changeset: GridRowsChangeset) -> FlowyResult<()> { + send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridRow) .payload(changeset) .send(); Ok(()) @@ -253,22 +254,6 @@ impl GridBlockMetaEditorManager { .send(); Ok(()) } - - #[allow(dead_code)] - async fn notify_did_update_row(&self, row_id: &str, field_metas: &[FieldMeta]) -> FlowyResult<()> { - match self.get_row_meta(row_id).await? { - None => {} - Some(row_meta) => { - let row_metas = vec![row_meta]; - if let Some(row) = make_rows_from_row_metas(field_metas, &row_metas).pop() { - send_dart_notification(row_id, GridNotification::DidUpdateRow) - .payload(row) - .send(); - } - } - } - Ok(()) - } } async fn make_block_meta_editor_map( diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index b34e0fea65..2dd6e57ea5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -77,7 +77,7 @@ impl ClientGridEditor { Ok(grid.update_field_meta(changeset, deserializer)?) }) .await?; - let _ = self.notify_grid_did_update_field(&field_id).await?; + let _ = self.notify_did_update_grid_field(&field_id).await?; } else { let _ = self .modify(|grid| { @@ -87,7 +87,7 @@ impl ClientGridEditor { Ok(grid.create_field_meta(field_meta, start_field_id)?) }) .await?; - let _ = self.notify_grid_did_insert_field(&field_id).await?; + let _ = self.notify_did_insert_grid_field(&field_id).await?; } Ok(()) @@ -114,14 +114,14 @@ impl ClientGridEditor { .modify(|grid| Ok(grid.update_field_meta(params, json_deserializer)?)) .await?; - let _ = self.notify_grid_did_update_field(&field_id).await?; + let _ = self.notify_did_update_grid_field(&field_id).await?; Ok(()) } pub async fn replace_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { let field_id = field_meta.id.clone(); let _ = self.modify(|pad| Ok(pad.replace_field_meta(field_meta)?)).await?; - let _ = self.notify_grid_did_update_field(&field_id).await?; + let _ = self.notify_did_update_grid_field(&field_id).await?; Ok(()) } @@ -153,7 +153,7 @@ impl ClientGridEditor { .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?)) .await?; - let _ = self.notify_grid_did_update_field(field_id).await?; + let _ = self.notify_did_update_grid_field(field_id).await?; Ok(()) } @@ -164,7 +164,7 @@ impl ClientGridEditor { .modify(|grid| Ok(grid.duplicate_field_meta(field_id, &duplicated_field_id)?)) .await?; - let _ = self.notify_grid_did_insert_field(field_id).await?; + let _ = self.notify_did_insert_grid_field(field_id).await?; Ok(()) } @@ -462,7 +462,7 @@ impl ClientGridEditor { } #[tracing::instrument(level = "trace", skip_all, err)] - async fn notify_grid_did_insert_field(&self, field_id: &str) -> FlowyResult<()> { + async fn notify_did_insert_grid_field(&self, field_id: &str) -> FlowyResult<()> { if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { let index_field = IndexField::from_field_meta(field_meta, index); let notified_changeset = GridFieldChangeset::insert(&self.grid_id, vec![index_field]); @@ -472,7 +472,7 @@ impl ClientGridEditor { } #[tracing::instrument(level = "trace", skip_all, err)] - async fn notify_grid_did_update_field(&self, field_id: &str) -> FlowyResult<()> { + async fn notify_did_update_grid_field(&self, field_id: &str) -> FlowyResult<()> { let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; debug_assert!(field_metas.len() == 1); diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index f40b93233e..d91265e896 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -208,7 +208,7 @@ impl GridMetaPad { pub fn move_field( &mut self, field_id: &str, - from_index: usize, + _from_index: usize, to_index: usize, ) -> CollaborateResult> { self.modify_grid( From 917e15a1b759c645f30052dd1ff2596ae24d5487 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 17 Apr 2022 14:50:29 +0800 Subject: [PATCH 168/179] chore: remove listener --- .../application/grid/grid_service.dart | 14 +- .../application/grid/row/row_bloc.dart | 15 +- .../application/grid/row/row_service.dart | 139 +++++++++--------- 3 files changed, 93 insertions(+), 75 deletions(-) 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 0d24e9974c..080d6e79fc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -85,8 +85,9 @@ class GridFieldCache { _fieldNotifier.fields = [...fields]; } - void addListener({VoidCallback? listener, void Function(List)? onChanged, bool Function()? listenWhen}) { - _fieldNotifier.addListener(() { + VoidCallback addListener( + {VoidCallback? listener, void Function(List)? onChanged, bool Function()? listenWhen}) { + f() { if (listenWhen != null && listenWhen() == false) { return; } @@ -98,7 +99,14 @@ class GridFieldCache { if (listener != null) { listener(); } - }); + } + + _fieldNotifier.addListener(f); + return f; + } + + void removeListener(VoidCallback f) { + _fieldNotifier.removeListener(f); } void _deleteFields(List deletedFields) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 1f026a0af6..7d853ce97e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,4 +1,5 @@ import 'dart:collection'; + import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -13,9 +14,10 @@ typedef CellDataMap = LinkedHashMap; class RowBloc extends Bloc { final RowService _rowService; - final GridFieldCache _fieldCache; final GridRowCache _rowCache; + void Function()? _rowListenCallback; + void Function()? _fieldListenCallback; RowBloc({ required GridRow rowData, @@ -72,16 +74,23 @@ class RowBloc extends Bloc { @override Future close() async { + if (_rowListenCallback != null) { + _rowCache.removeRowListener(_rowListenCallback!); + } + + if (_fieldListenCallback != null) { + _fieldCache.removeListener(_fieldListenCallback!); + } return super.close(); } Future _startListening() async { - _fieldCache.addListener( + _fieldListenCallback = _fieldCache.addListener( listener: () => add(const RowEvent.fieldsDidUpdate()), listenWhen: () => !isClosed, ); - _rowCache.addRowListener( + _rowListenCallback = _rowCache.addRowListener( rowId: state.rowData.rowId, onUpdated: (row) => add(RowEvent.didUpdateRow(row)), listenWhen: () => !isClosed, diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index bed21d1691..9cb1ac81a9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,5 +1,4 @@ import 'dart:collection'; - import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; @@ -8,61 +7,10 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; - import 'package:app_flowy/workspace/application/grid/grid_listener.dart'; part 'row_service.freezed.dart'; -class RowService { - final String gridId; - final String rowId; - - RowService({required this.gridId, required this.rowId}); - - Future> createRow() { - CreateRowPayload payload = CreateRowPayload.create() - ..gridId = gridId - ..startRowId = rowId; - - return GridEventCreateRow(payload).send(); - } - - Future> moveRow(String rowId, int fromIndex, int toIndex) { - final payload = MoveItemPayload.create() - ..gridId = gridId - ..itemId = rowId - ..ty = MoveItemType.MoveRow - ..fromIndex = fromIndex - ..toIndex = toIndex; - - return GridEventMoveItem(payload).send(); - } - - Future> getRow() { - final payload = RowIdentifierPayload.create() - ..gridId = gridId - ..rowId = rowId; - - return GridEventGetRow(payload).send(); - } - - Future> deleteRow() { - final payload = RowIdentifierPayload.create() - ..gridId = gridId - ..rowId = rowId; - - return GridEventDeleteRow(payload).send(); - } - - Future> duplicateRow() { - final payload = RowIdentifierPayload.create() - ..gridId = gridId - ..rowId = rowId; - - return GridEventDuplicateRow(payload).send(); - } -} - class RowsNotifier extends ChangeNotifier { List _rows = []; GridRowChangeReason _changeReason = const InitialListState(); @@ -84,13 +32,12 @@ class RowsNotifier extends ChangeNotifier { class GridRowCache { final String gridId; - late GridRowListener _rowsListener; + final GridRowListener _rowsListener; final RowsNotifier _rowNotifier = RowsNotifier(); final HashMap _rowDataMap = HashMap(); UnmodifiableListView _fields = UnmodifiableListView([]); - GridRowCache({required this.gridId}) { - _rowsListener = GridRowListener(gridId: gridId); + GridRowCache({required this.gridId}) : _rowsListener = GridRowListener(gridId: gridId) { _rowsListener.rowsUpdateNotifier.addPublishListener((result) { result.fold( (changesets) { @@ -106,18 +53,18 @@ class GridRowCache { _rowsListener.start(); } - List get clonedRows => [..._rowNotifier.rows]; - Future dispose() async { await _rowsListener.stop(); _rowNotifier.dispose(); } + List get clonedRows => [..._rowNotifier.rows]; + void addListener({ void Function(List, GridRowChangeReason)? onChanged, bool Function()? listenWhen, }) { - listener() { + _rowNotifier.addListener(() { if (listenWhen != null && listenWhen() == false) { return; } @@ -125,17 +72,15 @@ class GridRowCache { if (onChanged != null) { onChanged(clonedRows, _rowNotifier._changeReason); } - } - - _rowNotifier.addListener(listener); + }); } - void addRowListener({ + VoidCallback addRowListener({ required String rowId, void Function(Row)? onUpdated, bool Function()? listenWhen, }) { - _rowNotifier.addListener(() { + f() { if (onUpdated == null) { return; } @@ -145,13 +90,19 @@ class GridRowCache { } _rowNotifier._changeReason.whenOrNull(update: (indexs) { - final updatedIndex = indexs.firstWhereOrNull((updatedIndex) => updatedIndex.rowId == rowId); final row = _rowDataMap[rowId]; - if (updatedIndex != null && row != null) { + if (indexs[rowId] != null && row != null) { onUpdated(row); } }); - }); + } + + _rowNotifier.addListener(f); + return f; + } + + void removeRowListener(VoidCallback callback) { + _rowNotifier.removeListener(callback); } Future> getRowData(String rowId) async { @@ -234,7 +185,7 @@ class GridRowCache { return; } - final UpdatedIndexs updatedIndexs = []; + final UpdatedIndexs updatedIndexs = UpdatedIndexs(); final List newRows = _rowNotifier.rows; for (final rowOrder in updatedRows) { final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); @@ -242,7 +193,7 @@ class GridRowCache { newRows.removeAt(index); newRows.insert(index, GridRow.fromBlockRow(gridId, rowOrder, _fields)); _rowDataMap.remove(rowOrder.rowId); - updatedIndexs.add(UpdatedIndex(index: index, rowId: rowOrder.rowId)); + updatedIndexs[rowOrder.rowId] = UpdatedIndex(index: index, rowId: rowOrder.rowId); } } @@ -250,6 +201,56 @@ class GridRowCache { } } +class RowService { + final String gridId; + final String rowId; + + RowService({required this.gridId, required this.rowId}); + + Future> createRow() { + CreateRowPayload payload = CreateRowPayload.create() + ..gridId = gridId + ..startRowId = rowId; + + return GridEventCreateRow(payload).send(); + } + + Future> moveRow(String rowId, int fromIndex, int toIndex) { + final payload = MoveItemPayload.create() + ..gridId = gridId + ..itemId = rowId + ..ty = MoveItemType.MoveRow + ..fromIndex = fromIndex + ..toIndex = toIndex; + + return GridEventMoveItem(payload).send(); + } + + Future> getRow() { + final payload = RowIdentifierPayload.create() + ..gridId = gridId + ..rowId = rowId; + + return GridEventGetRow(payload).send(); + } + + Future> deleteRow() { + final payload = RowIdentifierPayload.create() + ..gridId = gridId + ..rowId = rowId; + + return GridEventDeleteRow(payload).send(); + } + + Future> duplicateRow() { + final payload = RowIdentifierPayload.create() + ..gridId = gridId + ..rowId = rowId; + + return GridEventDuplicateRow(payload).send(); + } +} + @freezed class GridCellIdentifier with _$GridCellIdentifier { const factory GridCellIdentifier({ @@ -283,7 +284,7 @@ class GridRow with _$GridRow { typedef InsertedIndexs = List; typedef DeletedIndexs = List; -typedef UpdatedIndexs = List; +typedef UpdatedIndexs = LinkedHashMap; class InsertedIndex { int index; From 13e8c629881b96caccc47bc3a43d661611b04164 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 17 Apr 2022 15:15:34 +0800 Subject: [PATCH 169/179] fix: grid property list bugs --- .../app_flowy/lib/startup/deps_resolver.dart | 5 ++- .../grid/setting/property_bloc.dart | 15 +++++---- .../plugins/grid/src/grid_page.dart | 3 +- .../src/widgets/toolbar/grid_property.dart | 33 +++++++++++-------- .../src/widgets/toolbar/grid_setting.dart | 7 ++-- .../src/widgets/toolbar/grid_toolbar.dart | 7 ++-- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 7e26566367..1a51652458 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -17,7 +17,6 @@ import 'package:app_flowy/user/presentation/router.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; @@ -223,7 +222,7 @@ void _resolveGridDeps(GetIt getIt) { (typeOption, _) => NumberTypeOptionBloc(typeOption: typeOption), ); - getIt.registerFactoryParam>( - (gridId, fields) => GridPropertyBloc(gridId: gridId, fields: fields), + getIt.registerFactoryParam( + (gridId, cache) => GridPropertyBloc(gridId: gridId, fieldCache: cache), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart index bf87851ebb..c69b8062bf 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart @@ -11,11 +11,12 @@ part 'property_bloc.freezed.dart'; class GridPropertyBloc extends Bloc { final FieldService _service; final GridFieldCache _fieldCache; + Function()? _listenFieldCallback; - GridPropertyBloc({required String gridId, required List fields}) + GridPropertyBloc({required String gridId, required GridFieldCache fieldCache}) : _service = FieldService(gridId: gridId), - _fieldCache = GridFieldCache(gridId: gridId), - super(GridPropertyState.initial(gridId, fields)) { + _fieldCache = fieldCache, + super(GridPropertyState.initial(gridId, fieldCache.clonedFields)) { on( (event, emit) async { await event.map( @@ -42,13 +43,15 @@ class GridPropertyBloc extends Bloc { @override Future close() async { - await _fieldCache.dispose(); + if (_listenFieldCallback != null) { + _fieldCache.removeListener(_listenFieldCallback!); + } return super.close(); } void _startListening() { - _fieldCache.addListener( - onChanged: (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(_fieldCache.clonedFields)), + _listenFieldCallback = _fieldCache.addListener( + onChanged: (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields)), listenWhen: () => !isClosed, ); } 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 c4b937300e..a8d564c6c0 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 @@ -164,9 +164,10 @@ class _GridToolbarAdaptor extends StatelessWidget { Widget build(BuildContext context) { return BlocSelector( selector: (state) { + final fieldCache = context.read().fieldCache; return GridToolbarContext( gridId: state.gridId, - fields: state.fields, + fieldCache: fieldCache, ); }, builder: (context, toolbarContext) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index 75898d5ba7..bc108f78d7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:app_flowy/workspace/application/grid/setting/property_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart'; @@ -18,10 +19,10 @@ import 'package:styled_widget/styled_widget.dart'; class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { final String gridId; - final List fields; + final GridFieldCache fieldCache; const GridPropertyList({ required this.gridId, - required this.fields, + required this.fieldCache, Key? key, }) : super(key: key); @@ -43,7 +44,7 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { Widget build(BuildContext context) { return BlocProvider( create: (context) => - getIt(param1: gridId, param2: fields)..add(const GridPropertyEvent.initial()), + getIt(param1: gridId, param2: fieldCache)..add(const GridPropertyEvent.initial()), child: BlocBuilder( builder: (context, state) { final cells = state.fields.map((field) { @@ -91,17 +92,7 @@ class _GridPropertyCell extends StatelessWidget { Expanded( child: SizedBox( height: GridSize.typeOptionItemHeight, - child: FlowyButton( - text: FlowyText.medium(field.name, fontSize: 12), - hoverColor: theme.hover, - leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), - onTap: () { - FieldEditor( - gridId: gridId, - fieldContextLoader: FieldContextLoaderAdaptor(gridId: gridId, field: field), - ).show(context, anchorDirection: AnchorDirection.bottomRight); - }, - ), + child: _editFieldButton(theme, context), ), ), FlowyIconButton( @@ -115,4 +106,18 @@ class _GridPropertyCell extends StatelessWidget { ], ); } + + FlowyButton _editFieldButton(AppTheme theme, BuildContext context) { + return FlowyButton( + text: FlowyText.medium(field.name, fontSize: 12), + hoverColor: theme.hover, + leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), + onTap: () { + FieldEditor( + gridId: gridId, + fieldContextLoader: FieldContextLoaderAdaptor(gridId: gridId, field: field), + ).show(context, anchorDirection: AnchorDirection.bottomRight); + }, + ); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart index a67ddd290f..f6f00add9d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:app_flowy/workspace/application/grid/setting/setting_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/image.dart'; @@ -18,11 +19,11 @@ import 'grid_property.dart'; class GridSettingContext { final String gridId; - final List fields; + final GridFieldCache fieldCache; GridSettingContext({ required this.gridId, - required this.fields, + required this.fieldCache, }); } @@ -41,7 +42,7 @@ class GridSettingList extends StatelessWidget { case GridSettingAction.sortBy: break; case GridSettingAction.properties: - GridPropertyList(gridId: settingContext.gridId, fields: settingContext.fields).show(context); + GridPropertyList(gridId: settingContext.gridId, fieldCache: settingContext.fieldCache).show(context); break; } }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart index 9569f95225..4400260941 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/extension.dart'; @@ -12,10 +13,10 @@ import 'grid_setting.dart'; class GridToolbarContext { final String gridId; - final List fields; + final GridFieldCache fieldCache; GridToolbarContext({ required this.gridId, - required this.fields, + required this.fieldCache, }); } @@ -27,7 +28,7 @@ class GridToolbar extends StatelessWidget { Widget build(BuildContext context) { final settingContext = GridSettingContext( gridId: toolbarContext.gridId, - fields: toolbarContext.fields, + fieldCache: toolbarContext.fieldCache, ); return SizedBox( height: 40, From 0acc0b0e8165495133c832a25b571c12ca7dd3f8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 17 Apr 2022 15:39:33 +0800 Subject: [PATCH 170/179] fix: duplicate field --- frontend/rust-lib/flowy-grid/src/services/grid_editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2dd6e57ea5..d2312708b1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -164,7 +164,7 @@ impl ClientGridEditor { .modify(|grid| Ok(grid.duplicate_field_meta(field_id, &duplicated_field_id)?)) .await?; - let _ = self.notify_did_insert_grid_field(field_id).await?; + let _ = self.notify_did_insert_grid_field(&duplicated_field_id).await?; Ok(()) } From 006b3c38112e9774edb3bd1f69612a788c5b5707 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 17 Apr 2022 20:50:16 +0800 Subject: [PATCH 171/179] chore: fix unit test & warnings --- .github/workflows/rust_test.yml | 2 +- .../plugins/grid/src/widgets/toolbar/grid_setting.dart | 1 - .../plugins/grid/src/widgets/toolbar/grid_toolbar.dart | 1 - frontend/rust-lib/flowy-text-block/src/editor.rs | 9 +++++---- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml index 998f6378e1..30b1f15576 100644 --- a/.github/workflows/rust_test.yml +++ b/.github/workflows/rust_test.yml @@ -44,7 +44,7 @@ jobs: - name: Run rust-lib tests working-directory: frontend/rust-lib - run: RUST_LOG=info cargo test --no-default-features + run: RUST_LOG=info cargo test --no-default-features --features="sync" - name: Run shared-lib tests working-directory: shared-lib diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart index f6f00add9d..05a72a5504 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_setting.dart @@ -8,7 +8,6 @@ import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart index 4400260941..8d25189163 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_toolbar.dart @@ -3,7 +3,6 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/extension.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/rust-lib/flowy-text-block/src/editor.rs b/frontend/rust-lib/flowy-text-block/src/editor.rs index 55160010bf..d43fc24f1c 100644 --- a/frontend/rust-lib/flowy-text-block/src/editor.rs +++ b/frontend/rust-lib/flowy-text-block/src/editor.rs @@ -26,27 +26,28 @@ pub struct ClientTextBlockEditor { #[allow(dead_code)] rev_manager: Arc, #[cfg(feature = "sync")] - ws_manager: Arc, + ws_manager: Arc, edit_cmd_tx: EditorCommandSender, } impl ClientTextBlockEditor { + #[allow(unused_variables)] pub(crate) async fn new( doc_id: &str, user: Arc, mut rev_manager: RevisionManager, - _rev_web_socket: Arc, + rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { let document_info = rev_manager.load::(Some(cloud_service)).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); - let _user_id = user.user_id()?; + let user_id = user.user_id()?; let edit_cmd_tx = spawn_edit_queue(user, rev_manager.clone(), delta); #[cfg(feature = "sync")] - let ws_manager = make_block_ws_manager( + let ws_manager = crate::web_socket::make_block_ws_manager( doc_id.clone(), user_id.clone(), edit_cmd_tx.clone(), From 5ee4b8a2bcecf50a24bdedfbc5a250b8fde5a6ee Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 18 Apr 2022 17:17:42 +0800 Subject: [PATCH 172/179] chore: different color when create option for single-select or multi-select --- .../app_flowy/lib/startup/deps_resolver.dart | 10 - .../grid/cell/select_option_service.dart | 3 +- .../field/type_option/multi_select_bloc.dart | 8 +- .../field/type_option/single_select_bloc.dart | 9 +- .../type_option/type_option_service.dart | 31 ++- .../src/widgets/header/field_switcher.dart | 44 ++-- .../header/type_option/multi_select.dart | 17 +- .../header/type_option/single_select.dart | 17 +- .../dart_event/flowy-grid/dart_event.dart | 2 +- .../protobuf/flowy-grid/cell_entities.pb.dart | 67 +----- .../flowy-grid/cell_entities.pbjson.dart | 14 +- frontend/rust-lib/flowy-grid/Flowy.toml | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 38 ++- frontend/rust-lib/flowy-grid/src/event_map.rs | 2 +- .../src/protobuf/model/cell_entities.rs | 223 +++--------------- .../src/protobuf/proto/cell_entities.proto | 6 +- .../flowy-grid/src/services/cell/mod.rs | 3 - .../{cell => entities}/cell_entities.rs | 23 +- .../{field => entities}/field_entities.rs | 0 .../flowy-grid/src/services/entities/mod.rs | 7 + .../src/services/entities/row_entities.rs | 31 +++ .../flowy-grid/src/services/field/mod.rs | 2 - .../type_options/selection_type_option.rs | 60 ++++- .../flowy-grid/src/services/grid_editor.rs | 58 +++-- .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- 25 files changed, 281 insertions(+), 400 deletions(-) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/mod.rs rename frontend/rust-lib/flowy-grid/src/services/{cell => entities}/cell_entities.rs (79%) rename frontend/rust-lib/flowy-grid/src/services/{field => entities}/field_entities.rs (100%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/entities/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 1a51652458..13eeae9033 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -3,7 +3,6 @@ import 'package:app_flowy/user/application/user_listener.dart'; import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; @@ -19,7 +18,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -206,14 +204,6 @@ void _resolveGridDeps(GetIt getIt) { (context, _) => FieldSwitcherBloc(context), ); - getIt.registerFactoryParam( - (typeOption, fieldId) => SingleSelectTypeOptionBloc(typeOption, fieldId), - ); - - getIt.registerFactoryParam( - (typeOption, fieldId) => MultiSelectTypeOptionBloc(typeOption, fieldId), - ); - getIt.registerFactoryParam( (typeOption, _) => DateTypeOptionBloc(typeOption: typeOption), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart index 65a05e4a5b..c76f06adc9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; @@ -13,7 +14,7 @@ class SelectOptionService { required String rowId, required String name, }) { - return GridEventNewSelectOption(SelectOptionName.create()..name = name).send().then( + return TypeOptionService(gridId: gridId, fieldId: fieldId).newOption(name: name).then( (result) { return result.fold( (option) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart index c5a55e20e1..0d42612595 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart @@ -11,14 +11,14 @@ part 'multi_select_bloc.freezed.dart'; class MultiSelectTypeOptionBloc extends Bloc { final TypeOptionService service; - MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption, String fieldId) - : service = TypeOptionService(fieldId: fieldId), - super(MultiSelectTypeOptionState.initial(typeOption)) { + MultiSelectTypeOptionBloc(TypeOptionContext typeOptionContext) + : service = TypeOptionService(gridId: typeOptionContext.gridId, fieldId: typeOptionContext.field.id), + super(MultiSelectTypeOptionState.initial(MultiSelectTypeOption.fromBuffer(typeOptionContext.data))) { on( (event, emit) async { await event.map( createOption: (_CreateOption value) async { - final result = await service.newOption(value.optionName); + final result = await service.newOption(name: value.optionName); result.fold( (option) { emit(state.copyWith(typeOption: _insertOption(option))); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart index 82e4bba790..36a2f956b3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart @@ -12,17 +12,16 @@ class SingleSelectTypeOptionBloc extends Bloc( (event, emit) async { await event.map( createOption: (_CreateOption value) async { - final result = await service.newOption(value.optionName); + final result = await service.newOption(name: value.optionName); result.fold( (option) { emit(state.copyWith(typeOption: _insertOption(option))); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart index 0f0c2f067d..92f2263c5d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart @@ -1,17 +1,44 @@ +import 'dart:typed_data'; + import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; class TypeOptionService { + final String gridId; final String fieldId; + TypeOptionService({ + required this.gridId, required this.fieldId, }); - Future> newOption(String name, {bool selected = false}) { - final payload = SelectOptionName.create()..name = name; + Future> newOption({ + required String name, + }) { + final fieldIdentifier = FieldIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId; + + final payload = CreateSelectOptionPayload.create() + ..optionName = name + ..fieldIdentifier = fieldIdentifier; + return GridEventNewSelectOption(payload).send(); } } + +class TypeOptionContext { + final String gridId; + final Field field; + final Uint8List data; + const TypeOptionContext({ + required this.gridId, + required this.field, + required this.data, + }); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index 80ebd456e7..5d86b7249d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; +import 'package:dartz/dartz.dart' show Either; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -14,11 +14,14 @@ import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; + import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; + import 'field_type_extension.dart'; -import 'package:dartz/dartz.dart' show Either; import 'type_option/multi_select.dart'; import 'type_option/number.dart'; import 'type_option/single_select.dart'; @@ -58,11 +61,7 @@ class _FieldSwitcherState extends State { }, builder: (context, state) { List children = [_switchFieldTypeButton(context, state.field)]; - final typeOptionWidget = _typeOptionWidget( - context: context, - field: state.field, - data: state.typeOptionData, - ); + final typeOptionWidget = _typeOptionWidget(context: context, state: state); if (typeOptionWidget != null) { children.add(typeOptionWidget); @@ -111,8 +110,7 @@ class _FieldSwitcherState extends State { Widget? _typeOptionWidget({ required BuildContext context, - required Field field, - required TypeOptionData data, + required FieldSwitchState state, }) { final overlayDelegate = TypeOptionOverlayDelegate( showOverlay: _showOverlay, @@ -123,9 +121,14 @@ class _FieldSwitcherState extends State { context.read().add(FieldSwitchEvent.didUpdateTypeOptionData(data)); }); + final typeOptionContext = TypeOptionContext( + gridId: state.gridId, + field: state.field, + data: state.typeOptionData, + ); + final builder = _makeTypeOptionBuild( - field: field, - data: data, + typeOptionContext: typeOptionContext, overlayDelegate: overlayDelegate, dataDelegate: dataDelegate, ); @@ -165,24 +168,23 @@ abstract class TypeOptionBuilder { } TypeOptionBuilder _makeTypeOptionBuild({ - required Field field, - required TypeOptionData data, + required TypeOptionContext typeOptionContext, required TypeOptionOverlayDelegate overlayDelegate, required TypeOptionDataDelegate dataDelegate, }) { - switch (field.fieldType) { + switch (typeOptionContext.field.fieldType) { case FieldType.Checkbox: - return CheckboxTypeOptionBuilder(data); + return CheckboxTypeOptionBuilder(typeOptionContext.data); case FieldType.DateTime: - return DateTypeOptionBuilder(data, overlayDelegate, dataDelegate); + return DateTypeOptionBuilder(typeOptionContext.data, overlayDelegate, dataDelegate); case FieldType.SingleSelect: - return SingleSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); + return SingleSelectTypeOptionBuilder(typeOptionContext, overlayDelegate, dataDelegate); case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); + return MultiSelectTypeOptionBuilder(typeOptionContext, overlayDelegate, dataDelegate); case FieldType.Number: - return NumberTypeOptionBuilder(data, overlayDelegate, dataDelegate); + return NumberTypeOptionBuilder(typeOptionContext.data, overlayDelegate, dataDelegate); case FieldType.RichText: - return RichTextTypeOptionBuilder(data); + return RichTextTypeOptionBuilder(typeOptionContext.data); default: throw UnimplementedError; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 873a63ceef..fb5da57bec 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -1,7 +1,6 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -11,13 +10,11 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { final MultiSelectTypeOptionWidget _widget; MultiSelectTypeOptionBuilder( - String fieldId, - TypeOptionData typeOptionData, + TypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, TypeOptionDataDelegate dataDelegate, ) : _widget = MultiSelectTypeOptionWidget( - fieldId: fieldId, - typeOption: MultiSelectTypeOption.fromBuffer(typeOptionData), + typeOptionContext: typeOptionContext, overlayDelegate: overlayDelegate, dataDelegate: dataDelegate, ); @@ -27,13 +24,11 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { } class MultiSelectTypeOptionWidget extends TypeOptionWidget { - final String fieldId; - final MultiSelectTypeOption typeOption; + final TypeOptionContext typeOptionContext; final TypeOptionOverlayDelegate overlayDelegate; final TypeOptionDataDelegate dataDelegate; const MultiSelectTypeOptionWidget({ - required this.fieldId, - required this.typeOption, + required this.typeOptionContext, required this.overlayDelegate, required this.dataDelegate, Key? key, @@ -42,7 +37,7 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: typeOption, param2: fieldId), + create: (context) => MultiSelectTypeOptionBloc(typeOptionContext), child: BlocConsumer( listener: (context, state) { dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart index ba2668f851..89d2f63a2d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -1,7 +1,6 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_option_pannel.dart'; @@ -10,13 +9,11 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { final SingleSelectTypeOptionWidget _widget; SingleSelectTypeOptionBuilder( - String fieldId, - TypeOptionData typeOptionData, + TypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, TypeOptionDataDelegate dataDelegate, ) : _widget = SingleSelectTypeOptionWidget( - fieldId: fieldId, - typeOption: SingleSelectTypeOption.fromBuffer(typeOptionData), + typeOptionContext: typeOptionContext, dataDelegate: dataDelegate, overlayDelegate: overlayDelegate, ); @@ -26,13 +23,11 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { } class SingleSelectTypeOptionWidget extends TypeOptionWidget { - final String fieldId; - final SingleSelectTypeOption typeOption; + final TypeOptionContext typeOptionContext; final TypeOptionOverlayDelegate overlayDelegate; final TypeOptionDataDelegate dataDelegate; const SingleSelectTypeOptionWidget({ - required this.fieldId, - required this.typeOption, + required this.typeOptionContext, required this.dataDelegate, required this.overlayDelegate, Key? key, @@ -41,7 +36,7 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: typeOption, param2: fieldId), + create: (context) => SingleSelectTypeOptionBloc(typeOptionContext), child: BlocConsumer( listener: (context, state) { dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); 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 33925ca955..9f87c2ad26 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 @@ -172,7 +172,7 @@ class GridEventMoveItem { } class GridEventNewSelectOption { - SelectOptionName request; + CreateSelectOptionPayload request; GridEventNewSelectOption(this.request); Future> send() { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart index 259fcf1422..7645632fb8 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart @@ -9,21 +9,23 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'field_entities.pb.dart' as $0; + class CreateSelectOptionPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) - ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellIdentifier', subBuilder: CellIdentifierPayload.create) + ..aOM<$0.FieldIdentifierPayload>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldIdentifier', subBuilder: $0.FieldIdentifierPayload.create) ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') ..hasRequiredFields = false ; CreateSelectOptionPayload._() : super(); factory CreateSelectOptionPayload({ - CellIdentifierPayload? cellIdentifier, + $0.FieldIdentifierPayload? fieldIdentifier, $core.String? optionName, }) { final _result = create(); - if (cellIdentifier != null) { - _result.cellIdentifier = cellIdentifier; + if (fieldIdentifier != null) { + _result.fieldIdentifier = fieldIdentifier; } if (optionName != null) { _result.optionName = optionName; @@ -52,15 +54,15 @@ class CreateSelectOptionPayload extends $pb.GeneratedMessage { static CreateSelectOptionPayload? _defaultInstance; @$pb.TagNumber(1) - CellIdentifierPayload get cellIdentifier => $_getN(0); + $0.FieldIdentifierPayload get fieldIdentifier => $_getN(0); @$pb.TagNumber(1) - set cellIdentifier(CellIdentifierPayload v) { setField(1, v); } + set fieldIdentifier($0.FieldIdentifierPayload v) { setField(1, v); } @$pb.TagNumber(1) - $core.bool hasCellIdentifier() => $_has(0); + $core.bool hasFieldIdentifier() => $_has(0); @$pb.TagNumber(1) - void clearCellIdentifier() => clearField(1); + void clearFieldIdentifier() => clearField(1); @$pb.TagNumber(1) - CellIdentifierPayload ensureCellIdentifier() => $_ensure(0); + $0.FieldIdentifierPayload ensureFieldIdentifier() => $_ensure(0); @$pb.TagNumber(2) $core.String get optionName => $_getSZ(1); @@ -147,50 +149,3 @@ class CellIdentifierPayload extends $pb.GeneratedMessage { void clearRowId() => clearField(3); } -class SelectOptionName extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionName', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..hasRequiredFields = false - ; - - SelectOptionName._() : super(); - factory SelectOptionName({ - $core.String? name, - }) { - final _result = create(); - if (name != null) { - _result.name = name; - } - return _result; - } - factory SelectOptionName.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory SelectOptionName.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') - SelectOptionName clone() => SelectOptionName()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SelectOptionName copyWith(void Function(SelectOptionName) updates) => super.copyWith((message) => updates(message as SelectOptionName)) as SelectOptionName; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static SelectOptionName create() => SelectOptionName._(); - SelectOptionName createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SelectOptionName getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static SelectOptionName? _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); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart index ac0c9add9c..931b310a69 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart @@ -12,13 +12,13 @@ import 'dart:typed_data' as $typed_data; const CreateSelectOptionPayload$json = const { '1': 'CreateSelectOptionPayload', '2': const [ - const {'1': 'cell_identifier', '3': 1, '4': 1, '5': 11, '6': '.CellIdentifierPayload', '10': 'cellIdentifier'}, + const {'1': 'field_identifier', '3': 1, '4': 1, '5': 11, '6': '.FieldIdentifierPayload', '10': 'fieldIdentifier'}, const {'1': 'option_name', '3': 2, '4': 1, '5': 9, '10': 'optionName'}, ], }; /// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEj8KD2NlbGxfaWRlbnRpZmllchgBIAEoCzIWLkNlbGxJZGVudGlmaWVyUGF5bG9hZFIOY2VsbElkZW50aWZpZXISHwoLb3B0aW9uX25hbWUYAiABKAlSCm9wdGlvbk5hbWU='); +final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEkIKEGZpZWxkX2lkZW50aWZpZXIYASABKAsyFy5GaWVsZElkZW50aWZpZXJQYXlsb2FkUg9maWVsZElkZW50aWZpZXISHwoLb3B0aW9uX25hbWUYAiABKAlSCm9wdGlvbk5hbWU='); @$core.Deprecated('Use cellIdentifierPayloadDescriptor instead') const CellIdentifierPayload$json = const { '1': 'CellIdentifierPayload', @@ -31,13 +31,3 @@ const CellIdentifierPayload$json = const { /// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); -@$core.Deprecated('Use selectOptionNameDescriptor instead') -const SelectOptionName$json = const { - '1': 'SelectOptionName', - '2': const [ - const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, - ], -}; - -/// Descriptor for `SelectOptionName`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionNameDescriptor = $convert.base64Decode('ChBTZWxlY3RPcHRpb25OYW1lEhIKBG5hbWUYASABKAlSBG5hbWU='); diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index b0b15a1a2a..1d0d2baea8 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -2,9 +2,7 @@ proto_crates = [ "src/event_map.rs", "src/services/field/type_options", - "src/services/field/field_entities.rs", - "src/services/cell/cell_entities.rs", - "src/services/row/row_entities.rs", + "src/services/entities", "src/dart_notification.rs" ] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 9efdf0d01f..2ef933f039 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,10 +1,8 @@ use crate::manager::GridManager; -use crate::services::cell::cell_entities::*; -use crate::services::field::field_entities::*; +use crate::services::entities::*; use crate::services::field::type_options::*; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str}; use crate::services::grid_editor::ClientGridEditor; -use crate::services::row::row_entities::*; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; @@ -248,9 +246,20 @@ pub(crate) async fn update_cell_handler( } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn new_select_option_handler(data: Data) -> DataResult { - let params = data.into_inner(); - data_result(SelectOption::new(¶ms.name)) +pub(crate) async fn new_select_option_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CreateSelectOptionParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_field_meta(¶ms.field_id).await { + None => Err(ErrorCode::InvalidData.into()), + Some(field_meta) => { + let type_option = select_option_operation(&field_meta)?; + let select_option = type_option.create_option(¶ms.option_name); + data_result(select_option) + } + } } #[tracing::instrument(level = "debug", skip_all, err)] @@ -337,20 +346,3 @@ pub(crate) async fn update_cell_select_option_handler( let _ = editor.update_cell(changeset).await?; Ok(()) } - -fn select_option_operation(field_meta: &FieldMeta) -> FlowyResult> { - match &field_meta.field_type { - FieldType::SingleSelect => { - let type_option = SingleSelectTypeOption::from(field_meta); - Ok(Box::new(type_option)) - } - FieldType::MultiSelect => { - let type_option = MultiSelectTypeOption::from(field_meta); - Ok(Box::new(type_option)) - } - ty => { - tracing::error!("Unsupported field type: {:?} for this handler", ty); - Err(ErrorCode::FieldInvalidOperation.into()) - } - } -} diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 67cbebe2d9..46513a43c9 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -69,7 +69,7 @@ pub enum GridEvent { #[event(input = "MoveItemPayload")] MoveItem = 17, - #[event(input = "SelectOptionName", output = "SelectOption")] + #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] NewSelectOption = 30, #[event(input = "CellIdentifierPayload", output = "SelectOptionContext")] diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs index 107f783e59..08a0cb0c1d 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs @@ -26,7 +26,7 @@ #[derive(PartialEq,Clone,Default)] pub struct CreateSelectOptionPayload { // message fields - pub cell_identifier: ::protobuf::SingularPtrField, + pub field_identifier: ::protobuf::SingularPtrField, pub option_name: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -44,37 +44,37 @@ impl CreateSelectOptionPayload { ::std::default::Default::default() } - // .CellIdentifierPayload cell_identifier = 1; + // .FieldIdentifierPayload field_identifier = 1; - pub fn get_cell_identifier(&self) -> &CellIdentifierPayload { - self.cell_identifier.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_field_identifier(&self) -> &super::field_entities::FieldIdentifierPayload { + self.field_identifier.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_cell_identifier(&mut self) { - self.cell_identifier.clear(); + pub fn clear_field_identifier(&mut self) { + self.field_identifier.clear(); } - pub fn has_cell_identifier(&self) -> bool { - self.cell_identifier.is_some() + pub fn has_field_identifier(&self) -> bool { + self.field_identifier.is_some() } // Param is passed by value, moved - pub fn set_cell_identifier(&mut self, v: CellIdentifierPayload) { - self.cell_identifier = ::protobuf::SingularPtrField::some(v); + pub fn set_field_identifier(&mut self, v: super::field_entities::FieldIdentifierPayload) { + self.field_identifier = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_cell_identifier(&mut self) -> &mut CellIdentifierPayload { - if self.cell_identifier.is_none() { - self.cell_identifier.set_default(); + pub fn mut_field_identifier(&mut self) -> &mut super::field_entities::FieldIdentifierPayload { + if self.field_identifier.is_none() { + self.field_identifier.set_default(); } - self.cell_identifier.as_mut().unwrap() + self.field_identifier.as_mut().unwrap() } // Take field - pub fn take_cell_identifier(&mut self) -> CellIdentifierPayload { - self.cell_identifier.take().unwrap_or_else(|| CellIdentifierPayload::new()) + pub fn take_field_identifier(&mut self) -> super::field_entities::FieldIdentifierPayload { + self.field_identifier.take().unwrap_or_else(|| super::field_entities::FieldIdentifierPayload::new()) } // string option_name = 2; @@ -106,7 +106,7 @@ impl CreateSelectOptionPayload { impl ::protobuf::Message for CreateSelectOptionPayload { fn is_initialized(&self) -> bool { - for v in &self.cell_identifier { + for v in &self.field_identifier { if !v.is_initialized() { return false; } @@ -119,7 +119,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.cell_identifier)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_identifier)?; }, 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.option_name)?; @@ -136,7 +136,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if let Some(ref v) = self.cell_identifier.as_ref() { + if let Some(ref v) = self.field_identifier.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -149,7 +149,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let Some(ref v) = self.cell_identifier.as_ref() { + if let Some(ref v) = self.field_identifier.as_ref() { os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -195,10 +195,10 @@ impl ::protobuf::Message for CreateSelectOptionPayload { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "cell_identifier", - |m: &CreateSelectOptionPayload| { &m.cell_identifier }, - |m: &mut CreateSelectOptionPayload| { &mut m.cell_identifier }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field_identifier", + |m: &CreateSelectOptionPayload| { &m.field_identifier }, + |m: &mut CreateSelectOptionPayload| { &mut m.field_identifier }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "option_name", @@ -221,7 +221,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { impl ::protobuf::Clear for CreateSelectOptionPayload { fn clear(&mut self) { - self.cell_identifier.clear(); + self.field_identifier.clear(); self.option_name.clear(); self.unknown_fields.clear(); } @@ -482,173 +482,14 @@ impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { } } -#[derive(PartialEq,Clone,Default)] -pub struct SelectOptionName { - // 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 SelectOptionName { - fn default() -> &'a SelectOptionName { - ::default_instance() - } -} - -impl SelectOptionName { - pub fn new() -> SelectOptionName { - ::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 SelectOptionName { - 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() -> SelectOptionName { - SelectOptionName::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: &SelectOptionName| { &m.name }, - |m: &mut SelectOptionName| { &mut m.name }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOptionName", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SelectOptionName { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOptionName::new) - } -} - -impl ::protobuf::Clear for SelectOptionName { - fn clear(&mut self) { - self.name.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SelectOptionName { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOptionName { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x13cell_entities.proto\"}\n\x19CreateSelectOptionPayload\x12?\n\x0fce\ - ll_identifier\x18\x01\x20\x01(\x0b2\x16.CellIdentifierPayloadR\x0ecellId\ - entifier\x12\x1f\n\x0boption_name\x18\x02\x20\x01(\tR\noptionName\"b\n\ - \x15CellIdentifierPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ - idId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06r\ - ow_id\x18\x03\x20\x01(\tR\x05rowId\"&\n\x10SelectOptionName\x12\x12\n\ - \x04name\x18\x01\x20\x01(\tR\x04nameb\x06proto3\ + \n\x13cell_entities.proto\x1a\x14field_entities.proto\"\x80\x01\n\x19Cre\ + ateSelectOptionPayload\x12B\n\x10field_identifier\x18\x01\x20\x01(\x0b2\ + \x17.FieldIdentifierPayloadR\x0ffieldIdentifier\x12\x1f\n\x0boption_name\ + \x18\x02\x20\x01(\tR\noptionName\"b\n\x15CellIdentifierPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\ + \x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ + b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto index d20ec4e34c..558ed90034 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto @@ -1,7 +1,8 @@ syntax = "proto3"; +import "field_entities.proto"; message CreateSelectOptionPayload { - CellIdentifierPayload cell_identifier = 1; + FieldIdentifierPayload field_identifier = 1; string option_name = 2; } message CellIdentifierPayload { @@ -9,6 +10,3 @@ message CellIdentifierPayload { string field_id = 2; string row_id = 3; } -message SelectOptionName { - string name = 1; -} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs deleted file mode 100644 index d2541866be..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub(crate) mod cell_entities; - -pub use cell_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/services/entities/cell_entities.rs similarity index 79% rename from frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/entities/cell_entities.rs index 0947e37f06..2f408db992 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/entities/cell_entities.rs @@ -1,3 +1,4 @@ +use crate::services::entities::{FieldIdentifier, FieldIdentifierPayload}; use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; use flowy_grid_data_model::parser::NotEmptyStr; @@ -5,25 +6,33 @@ use flowy_grid_data_model::parser::NotEmptyStr; #[derive(ProtoBuf, Default)] pub struct CreateSelectOptionPayload { #[pb(index = 1)] - pub cell_identifier: CellIdentifierPayload, + pub field_identifier: FieldIdentifierPayload, #[pb(index = 2)] pub option_name: String, } pub struct CreateSelectOptionParams { - pub cell_identifier: CellIdentifier, + pub field_identifier: FieldIdentifier, pub option_name: String, } +impl std::ops::Deref for CreateSelectOptionParams { + type Target = FieldIdentifier; + + fn deref(&self) -> &Self::Target { + &self.field_identifier + } +} + impl TryInto for CreateSelectOptionPayload { type Error = ErrorCode; fn try_into(self) -> Result { let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; - let cell_identifier = self.cell_identifier.try_into()?; + let field_identifier = self.field_identifier.try_into()?; Ok(CreateSelectOptionParams { - cell_identifier, + field_identifier, option_name: option_name.0, }) } @@ -61,9 +70,3 @@ impl TryInto for CellIdentifierPayload { }) } } - -#[derive(ProtoBuf, Default)] -pub struct SelectOptionName { - #[pb(index = 1)] - pub name: String, -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs b/frontend/rust-lib/flowy-grid/src/services/entities/field_entities.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/entities/field_entities.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/entities/mod.rs b/frontend/rust-lib/flowy-grid/src/services/entities/mod.rs new file mode 100644 index 0000000000..61bcf6ebed --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/entities/mod.rs @@ -0,0 +1,7 @@ +mod cell_entities; +mod field_entities; +mod row_entities; + +pub use cell_entities::*; +pub use field_entities::*; +pub use row_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs b/frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs new file mode 100644 index 0000000000..c97becbd34 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs @@ -0,0 +1,31 @@ +use flowy_derive::ProtoBuf; +use flowy_error::ErrorCode; +use flowy_grid_data_model::parser::NotEmptyStr; + +#[derive(ProtoBuf, Default)] +pub struct RowIdentifierPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 3)] + pub row_id: String, +} + +pub struct RowIdentifier { + pub grid_id: String, + pub row_id: String, +} + +impl TryInto for RowIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(RowIdentifier { + grid_id: grid_id.0, + row_id: row_id.0, + }) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 89a1f05c57..c1b689fbf4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,7 +1,5 @@ mod field_builder; -pub(crate) mod field_entities; pub(crate) mod type_options; pub use field_builder::*; -pub use field_entities::*; pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index a80f5760ac..ecaf2344b8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; -use crate::services::cell::{CellIdentifier, CellIdentifierPayload}; +use crate::services::entities::{CellIdentifier, CellIdentifierPayload}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::{ErrorCode, FlowyError}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, }; @@ -36,10 +36,35 @@ pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync { } } + fn create_option(&self, name: &str) -> SelectOption { + let color = select_option_color_from_index(self.options().len()); + SelectOption::with_color(name, color) + } + fn option_context(&self, cell_meta: &Option) -> SelectOptionContext; + + fn options(&self) -> &Vec; + fn mut_options(&mut self) -> &mut Vec; } +pub fn select_option_operation(field_meta: &FieldMeta) -> FlowyResult> { + match &field_meta.field_type { + FieldType::SingleSelect => { + let type_option = SingleSelectTypeOption::from(field_meta); + Ok(Box::new(type_option)) + } + FieldType::MultiSelect => { + let type_option = MultiSelectTypeOption::from(field_meta); + Ok(Box::new(type_option)) + } + ty => { + tracing::error!("Unsupported field type: {:?} for this handler", ty); + Err(ErrorCode::FieldInvalidOperation.into()) + } + } +} + // Single select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SingleSelectTypeOption { @@ -60,6 +85,10 @@ impl SelectOptionOperation for SingleSelectTypeOption { } } + fn options(&self) -> &Vec { + &self.options + } + fn mut_options(&mut self) -> &mut Vec { &mut self.options } @@ -155,6 +184,10 @@ impl SelectOptionOperation for MultiSelectTypeOption { } } + fn options(&self) -> &Vec { + &self.options + } + fn mut_options(&mut self) -> &mut Vec { &mut self.options } @@ -265,6 +298,14 @@ impl SelectOption { color: SelectOptionColor::default(), } } + + pub fn with_color(name: &str, color: SelectOptionColor) -> Self { + SelectOption { + id: nanoid!(4), + name: name.to_owned(), + color, + } + } } #[derive(Clone, Debug, Default, ProtoBuf)] @@ -430,6 +471,21 @@ pub enum SelectOptionColor { Blue = 8, } +pub fn select_option_color_from_index(index: usize) -> SelectOptionColor { + match index % 8 { + 0 => SelectOptionColor::Purple, + 1 => SelectOptionColor::Pink, + 2 => SelectOptionColor::LightPink, + 3 => SelectOptionColor::Orange, + 4 => SelectOptionColor::Yellow, + 5 => SelectOptionColor::Lime, + 6 => SelectOptionColor::Green, + 7 => SelectOptionColor::Aqua, + 8 => SelectOptionColor::Blue, + _ => SelectOptionColor::Purple, + } +} + impl std::default::Default for SelectOptionColor { fn default() -> Self { SelectOptionColor::Purple 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 d2312708b1..724ec65e8f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,8 +1,11 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_manager::GridBlockMetaEditorManager; -use crate::services::cell::CellIdentifier; -use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; +use crate::services::entities::{CellIdentifier, CreateSelectOptionParams}; +use crate::services::field::{ + default_type_option_builder_from_type, select_option_operation, type_option_builder_from_bytes, FieldBuilder, + SelectOption, +}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; use bytes::Bytes; @@ -22,7 +25,7 @@ use tokio::sync::RwLock; pub struct ClientGridEditor { grid_id: String, user: Arc, - pad: Arc>, + grid_pad: Arc>, rev_manager: Arc, block_meta_manager: Arc, } @@ -38,14 +41,14 @@ impl ClientGridEditor { let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); - let pad = Arc::new(RwLock::new(grid_pad)); - let blocks = pad.read().await.get_block_metas(); + let grid_pad = Arc::new(RwLock::new(grid_pad)); + let blocks = grid_pad.read().await.get_block_metas(); let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, blocks, persistence).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, - pad, + grid_pad, rev_manager, block_meta_manager, })) @@ -94,18 +97,18 @@ impl ClientGridEditor { } pub async fn create_next_field_meta(&self, field_type: &FieldType) -> FlowyResult { - let name = format!("Property {}", self.pad.read().await.fields().len() + 1); + let name = format!("Property {}", self.grid_pad.read().await.fields().len() + 1); let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build(); Ok(field_meta) } pub async fn contain_field(&self, field_id: &str) -> bool { - self.pad.read().await.contain_field(field_id) + self.grid_pad.read().await.contain_field(field_id) } pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let field_id = params.field_id.clone(); - let json_deserializer = match self.pad.read().await.get_field_meta(params.field_id.as_str()) { + let json_deserializer = match self.grid_pad.read().await.get_field_meta(params.field_id.as_str()) { None => return Err(ErrorCode::FieldDoesNotExist.into()), Some((_, field_meta)) => TypeOptionJsonDeserializer(field_meta.field_type.clone()), }; @@ -169,7 +172,7 @@ impl ClientGridEditor { } pub async fn get_field_meta(&self, field_id: &str) -> Option { - let field_meta = self.pad.read().await.get_field_meta(field_id)?.1.clone(); + let field_meta = self.grid_pad.read().await.get_field_meta(field_id)?.1.clone(); Some(field_meta) } @@ -178,14 +181,14 @@ impl ClientGridEditor { T: Into, { if field_ids.is_none() { - let field_metas = self.pad.read().await.get_field_metas(None)?; + let field_metas = self.grid_pad.read().await.get_field_metas(None)?; return Ok(field_metas); } let to_field_orders = |item: Vec| item.into_iter().map(|data| data.into()).collect(); let field_orders = field_ids.map_or(vec![], to_field_orders); let expected_len = field_orders.len(); - let field_metas = self.pad.read().await.get_field_metas(Some(field_orders))?; + let field_metas = self.grid_pad.read().await.get_field_metas(Some(field_orders))?; if expected_len != 0 && field_metas.len() != expected_len { tracing::error!( "This is a bug. The len of the field_metas should equal to {}", @@ -207,7 +210,7 @@ impl ClientGridEditor { } pub async fn create_row(&self, start_row_id: Option) -> FlowyResult { - let field_metas = self.pad.read().await.get_field_metas(None)?; + let field_metas = self.grid_pad.read().await.get_field_metas(None)?; let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id @@ -314,7 +317,7 @@ impl ClientGridEditor { let cell_data_changeset = changeset.data.unwrap(); let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?; tracing::trace!("{}: {:?}", &changeset.field_id, cell_meta); - match self.pad.read().await.get_field_meta(&changeset.field_id) { + match self.grid_pad.read().await.get_field_meta(&changeset.field_id) { None => { let msg = format!("Field not found with id: {}", &changeset.field_id); Err(FlowyError::internal().context(msg)) @@ -334,7 +337,7 @@ impl ClientGridEditor { } pub async fn get_block_metas(&self) -> FlowyResult> { - let grid_blocks = self.pad.read().await.get_block_metas(); + let grid_blocks = self.grid_pad.read().await.get_block_metas(); Ok(grid_blocks) } @@ -347,7 +350,7 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> FlowyResult { - let pad_read_guard = self.pad.read().await; + let pad_read_guard = self.grid_pad.read().await; let field_orders = pad_read_guard.get_field_orders(); let mut block_orders = vec![]; for block_order in pad_read_guard.get_block_metas() { @@ -369,7 +372,7 @@ impl ClientGridEditor { pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { let block_ids = match block_ids { None => self - .pad + .grid_pad .read() .await .get_block_metas() @@ -396,7 +399,7 @@ impl ClientGridEditor { let _ = self .modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?)) .await?; - if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { + if let Some((index, field_meta)) = self.grid_pad.read().await.get_field_meta(field_id) { let delete_field_order = FieldOrder::from(field_id); let insert_field = IndexField::from_field_meta(field_meta, index); let notified_changeset = GridFieldChangeset { @@ -420,14 +423,14 @@ impl ClientGridEditor { } pub async fn delta_bytes(&self) -> Bytes { - self.pad.read().await.delta_bytes() + self.grid_pad.read().await.delta_bytes() } async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { - let mut write_guard = self.pad.write().await; + let mut write_guard = self.grid_pad.write().await; if let Some(changeset) = f(&mut *write_guard)? { let _ = self.apply_change(changeset).await?; } @@ -455,7 +458,7 @@ impl ClientGridEditor { } async fn block_id(&self) -> FlowyResult { - match self.pad.read().await.get_block_metas().last() { + match self.grid_pad.read().await.get_block_metas().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), Some(grid_block) => Ok(grid_block.block_id.clone()), } @@ -463,7 +466,7 @@ impl ClientGridEditor { #[tracing::instrument(level = "trace", skip_all, err)] async fn notify_did_insert_grid_field(&self, field_id: &str) -> FlowyResult<()> { - if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { + if let Some((index, field_meta)) = self.grid_pad.read().await.get_field_meta(field_id) { let index_field = IndexField::from_field_meta(field_meta, index); let notified_changeset = GridFieldChangeset::insert(&self.grid_id, vec![index_field]); let _ = self.notify_did_update_grid(notified_changeset).await?; @@ -473,10 +476,13 @@ impl ClientGridEditor { #[tracing::instrument(level = "trace", skip_all, err)] async fn notify_did_update_grid_field(&self, field_id: &str) -> FlowyResult<()> { - let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; - debug_assert!(field_metas.len() == 1); - - if let Some(field_meta) = field_metas.pop() { + if let Some((_, field_meta)) = self + .grid_pad + .read() + .await + .get_field_meta(field_id) + .map(|(index, field)| (index, field.clone())) + { let updated_field = Field::from(field_meta); let notified_changeset = GridFieldChangeset::update(&self.grid_id, vec![updated_field.clone()]); let _ = self.notify_did_update_grid(notified_changeset).await?; diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index d6ca2d5c45..036efd6ada 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -2,7 +2,7 @@ mod util; pub mod block_meta_editor; mod block_meta_manager; -pub mod cell; +pub mod entities; pub mod field; pub mod grid_editor; pub mod persistence; From b3a99be7f88d3b90d5d2c75cba6f9ab40382ab2e Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 19 Apr 2022 11:41:37 +0800 Subject: [PATCH 173/179] chore: refactor row cache --- .../workspace/application/grid/grid_bloc.dart | 4 +- .../application/grid/row/row_bloc.dart | 33 ++-- .../application/grid/row/row_service.dart | 187 +++++++++++------- .../plugins/grid/src/grid_page.dart | 6 +- .../cell/selection_cell/selection_cell.dart | 4 +- .../grid/src/widgets/row/grid_row.dart | 1 - 6 files changed, 133 insertions(+), 102 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 f38e874453..6e19f1f3a5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -51,13 +51,13 @@ class GridBloc extends Bloc { void _startListening() { fieldCache.addListener( - onChanged: (fields) => add(GridEvent.didReceiveFieldUpdate(fields)), listenWhen: () => !isClosed, + onChanged: (fields) => add(GridEvent.didReceiveFieldUpdate(fields)), ); rowCache.addListener( - onChanged: (rows, listState) => add(GridEvent.didReceiveRowUpdate(rowCache.clonedRows, listState)), listenWhen: () => !isClosed, + onChanged: (rows, listState) => add(GridEvent.didReceiveRowUpdate(rowCache.clonedRows, listState)), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 7d853ce97e..5de5bcd4ab 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -53,23 +53,17 @@ class RowBloc extends Bloc { void _handleRowUpdate(Row row, Emitter emit) { final CellDataMap cellDataMap = _makeCellDatas(row, state.rowData.fields); - emit(state.copyWith( - row: Future(() => Some(row)), - cellDataMap: Some(cellDataMap), - )); + emit(state.copyWith(cellDataMap: Some(cellDataMap))); } Future _handleFieldUpdate(Emitter emit) async { - final optionRow = await state.row; - final CellDataMap cellDataMap = optionRow.fold( - () => CellDataMap.identity(), - (row) => _makeCellDatas(row, _fieldCache.unmodifiableFields), - ); + final data = state.rowData.data; + if (data == null) { + return; + } - emit(state.copyWith( - rowData: state.rowData.copyWith(fields: _fieldCache.unmodifiableFields), - cellDataMap: Some(cellDataMap), - )); + final CellDataMap cellDataMap = _makeCellDatas(data, state.rowData.fields); + emit(state.copyWith(cellDataMap: Some(cellDataMap))); } @override @@ -98,11 +92,12 @@ class RowBloc extends Bloc { } Future _loadRow(Emitter emit) async { - final data = await _rowCache.getRowData(state.rowData.rowId); - if (isClosed) { - return; - } - data.foldRight(null, (data, _) => add(RowEvent.didLoadRow(data))); + final data = _rowCache.loadRow(state.rowData.rowId); + data.foldRight(null, (data, _) { + if (!isClosed) { + add(RowEvent.didLoadRow(data)); + } + }); } CellDataMap _makeCellDatas(Row row, List fields) { @@ -134,13 +129,11 @@ class RowEvent with _$RowEvent { class RowState with _$RowState { const factory RowState({ required GridRow rowData, - required Future> row, required Option cellDataMap, }) = _RowState; factory RowState.initial(GridRow rowData) => RowState( rowData: rowData, - row: Future(() => none()), cellDataMap: none(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 9cb1ac81a9..d1b77f84e9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -1,4 +1,5 @@ import 'dart:collection'; + import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; @@ -7,37 +8,31 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; + import 'package:app_flowy/workspace/application/grid/grid_listener.dart'; part 'row_service.freezed.dart'; -class RowsNotifier extends ChangeNotifier { - List _rows = []; - GridRowChangeReason _changeReason = const InitialListState(); - - void updateRows(List rows, GridRowChangeReason changeReason) { - _rows = rows; - _changeReason = changeReason; - - changeReason.map( - insert: (_) => notifyListeners(), - delete: (_) => notifyListeners(), - update: (_) => notifyListeners(), - initial: (_) {}, - ); - } - - List get rows => _rows; -} - class GridRowCache { final String gridId; final GridRowListener _rowsListener; - final RowsNotifier _rowNotifier = RowsNotifier(); - final HashMap _rowDataMap = HashMap(); + late final _RowsNotifier _rowNotifier; UnmodifiableListView _fields = UnmodifiableListView([]); + List get clonedRows => _rowNotifier.clonedRows; + GridRowCache({required this.gridId}) : _rowsListener = GridRowListener(gridId: gridId) { + _rowNotifier = _RowsNotifier( + rowBuilder: (rowOrder) { + return GridRow( + gridId: gridId, + fields: _fields, + rowId: rowOrder.rowId, + height: rowOrder.height.toDouble(), + ); + }, + ); + _rowsListener.rowsUpdateNotifier.addPublishListener((result) { result.fold( (changesets) { @@ -58,8 +53,6 @@ class GridRowCache { _rowNotifier.dispose(); } - List get clonedRows => [..._rowNotifier.rows]; - void addListener({ void Function(List, GridRowChangeReason)? onChanged, bool Function()? listenWhen, @@ -80,7 +73,7 @@ class GridRowCache { void Function(Row)? onUpdated, bool Function()? listenWhen, }) { - f() { + listenrHandler() { if (onUpdated == null) { return; } @@ -90,57 +83,76 @@ class GridRowCache { } _rowNotifier._changeReason.whenOrNull(update: (indexs) { - final row = _rowDataMap[rowId]; + final row = _rowNotifier.rowDataWithId(rowId); if (indexs[rowId] != null && row != null) { onUpdated(row); } }); } - _rowNotifier.addListener(f); - return f; + _rowNotifier.addListener(listenrHandler); + return listenrHandler; } void removeRowListener(VoidCallback callback) { _rowNotifier.removeListener(callback); } - Future> getRowData(String rowId) async { - final Row? data = _rowDataMap[rowId]; + Option loadRow(String rowId) { + final Row? data = _rowNotifier.rowDataWithId(rowId); if (data != null) { - return Future(() => Some(data)); + return Some(data); } final payload = RowIdentifierPayload.create() ..gridId = gridId ..rowId = rowId; - final result = await GridEventGetRow(payload).send(); - return Future(() { - return result.fold( - (data) { - data.freeze(); - _rowDataMap[data.id] = data; - return Some(data); - }, - (err) { - Log.error(err); - return none(); - }, + GridEventGetRow(payload).send().then((result) { + result.fold( + (rowData) => _rowNotifier.rowData = rowData, + (err) => Log.error(err), ); }); + return none(); } void updateWithBlock(List blocks, UnmodifiableListView fields) { _fields = fields; - final newRows = blocks.expand((block) => block.rowOrders).map((rowOrder) { - return GridRow.fromBlockRow(gridId, rowOrder, _fields); - }).toList(); - - _rowNotifier.updateRows(newRows, const GridRowChangeReason.initial()); + final rowOrders = blocks.expand((block) => block.rowOrders).toList(); + _rowNotifier.reset(rowOrders); } void _deleteRows(List deletedRows) { + _rowNotifier.deleteRows(deletedRows); + } + + void _insertRows(List createdRows) { + _rowNotifier.insertRows(createdRows); + } + + void _updateRows(List rowOrders) { + _rowNotifier.updateRows(rowOrders); + } +} + +class _RowsNotifier extends ChangeNotifier { + List _rows = []; + HashMap _rowDataMap = HashMap(); + GridRowChangeReason _changeReason = const InitialListState(); + final GridRow Function(RowOrder) rowBuilder; + + _RowsNotifier({ + required this.rowBuilder, + }); + + void reset(List rowOrders) { + _rowDataMap = HashMap(); + final rows = rowOrders.map((rowOrder) => rowBuilder(rowOrder)).toList(); + _update(rows, const GridRowChangeReason.initial()); + } + + void deleteRows(List deletedRows) { if (deletedRows.isEmpty) { return; } @@ -149,7 +161,7 @@ class GridRowCache { final DeletedIndexs deletedIndex = []; final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; - _rowNotifier.rows.asMap().forEach((index, row) { + _rows.asMap().forEach((index, row) { if (deletedRowMap[row.rowId] == null) { newRows.add(row); } else { @@ -157,48 +169,81 @@ class GridRowCache { } }); - _rowNotifier.updateRows(newRows, GridRowChangeReason.delete(deletedIndex)); + _update(newRows, GridRowChangeReason.delete(deletedIndex)); } - void _insertRows(List createdRows) { + void insertRows(List createdRows) { if (createdRows.isEmpty) { return; } InsertedIndexs insertIndexs = []; - final List newRows = _rowNotifier.rows; + final List newRows = _rows; for (final createdRow in createdRows) { - final gridRow = GridRow.fromBlockRow(gridId, createdRow.rowOrder, _fields); - insertIndexs.add( - InsertedIndex( - index: createdRow.index, - rowId: gridRow.rowId, - ), - ); - newRows.insert(createdRow.index, gridRow); + final rowOrder = createdRow.rowOrder; + final insertIndex = InsertedIndex(index: createdRow.index, rowId: rowOrder.rowId); + insertIndexs.add(insertIndex); + newRows.insert(createdRow.index, (rowBuilder(rowOrder))); } - _rowNotifier.updateRows(newRows, GridRowChangeReason.insert(insertIndexs)); + _update(newRows, GridRowChangeReason.insert(insertIndexs)); } - void _updateRows(List updatedRows) { + void updateRows(List updatedRows) { if (updatedRows.isEmpty) { return; } final UpdatedIndexs updatedIndexs = UpdatedIndexs(); - final List newRows = _rowNotifier.rows; + final List newRows = _rows; for (final rowOrder in updatedRows) { final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); if (index != -1) { newRows.removeAt(index); - newRows.insert(index, GridRow.fromBlockRow(gridId, rowOrder, _fields)); + // Remove the cache data _rowDataMap.remove(rowOrder.rowId); + newRows.insert(index, rowBuilder(rowOrder)); updatedIndexs[rowOrder.rowId] = UpdatedIndex(index: index, rowId: rowOrder.rowId); } } - _rowNotifier.updateRows(newRows, GridRowChangeReason.update(updatedIndexs)); + _update(newRows, GridRowChangeReason.update(updatedIndexs)); } + + void _update(List rows, GridRowChangeReason changeReason) { + _rows = rows; + _changeReason = changeReason; + + changeReason.map( + insert: (_) => notifyListeners(), + delete: (_) => notifyListeners(), + update: (_) => notifyListeners(), + initial: (_) {}, + ); + } + + set rowData(Row rowData) { + rowData.freeze(); + + _rowDataMap[rowData.id] = rowData; + final index = _rows.indexWhere((row) => row.rowId == rowData.id); + if (index != -1) { + if (_rows[index].data != rowData) { + final row = _rows.removeAt(index).copyWith(data: rowData); + _rows.insert(index, row); + + final UpdatedIndexs updatedIndexs = UpdatedIndexs(); + updatedIndexs[row.rowId] = UpdatedIndex(index: index, rowId: row.rowId); + _changeReason = GridRowChangeReason.update(updatedIndexs); + notifyListeners(); + } + } + } + + Row? rowDataWithId(String rowId) { + return _rowDataMap[rowId]; + } + + List get clonedRows => [..._rows]; } class RowService { @@ -258,7 +303,7 @@ class GridCellIdentifier with _$GridCellIdentifier { required String rowId, required Field field, Cell? cell, - }) = _CellData; + }) = _GridCellIdentifier; } @freezed @@ -268,18 +313,8 @@ class GridRow with _$GridRow { required String rowId, required List fields, required double height, - required Future> data, + Row? data, }) = _GridRow; - - factory GridRow.fromBlockRow(String gridId, RowOrder row, List fields) { - return GridRow( - gridId: gridId, - fields: fields, - rowId: row.rowId, - data: Future(() => none()), - height: row.height.toDouble(), - ); - } } typedef InsertedIndexs = List; 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 a8d564c6c0..3303cde961 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 @@ -222,7 +222,11 @@ class _GridRowsState extends State<_GridRows> { ); } - Widget _renderRow(BuildContext context, GridRow rowData, Animation animation) { + Widget _renderRow( + BuildContext context, + GridRow rowData, + Animation animation, + ) { final bloc = context.read(); final fieldCache = bloc.fieldCache; final rowCache = bloc.rowCache; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 4e0cba65bb..15a7813397 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -47,7 +47,7 @@ class _SingleSelectCellState extends State { () => widget.setFocus(context, false), ); }, - child: Row(children: children), + child: ClipRRect(child: Row(children: children)), ), ); }, @@ -103,7 +103,7 @@ class _MultiSelectCellState extends State { () => widget.setFocus(context, false), ); }, - child: Row(children: children), + child: ClipRRect(child: Row(children: children)), ), ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 7f704991b7..316b5ec9c0 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -7,7 +7,6 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; - import 'row_action_sheet.dart'; class GridRowWidget extends StatefulWidget { From f40e0c18e654a4e2212490f8ae79364f58494487 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 19 Apr 2022 21:52:46 +0800 Subject: [PATCH 174/179] chore: refactor rowbloc --- .../app_flowy/lib/startup/deps_resolver.dart | 10 +- .../application/grid/cell/cell_service.dart | 4 +- .../grid/cell/checkbox_cell_bloc.dart | 6 +- .../application/grid/cell/date_cell_bloc.dart | 6 +- .../grid/cell/number_cell_bloc.dart | 6 +- .../grid/cell/selection_cell_bloc.dart | 6 +- .../grid/cell/selection_editor_bloc.dart | 4 +- .../application/grid/cell/text_cell_bloc.dart | 8 +- .../workspace/application/grid/grid_bloc.dart | 10 +- .../application/grid/grid_service.dart | 43 ++++++ .../application/grid/row/row_bloc.dart | 78 ++-------- .../application/grid/row/row_service.dart | 137 +++++++++++------- .../plugins/grid/src/grid_page.dart | 6 +- .../grid/src/widgets/cell/cell_builder.dart | 2 +- .../grid/src/widgets/cell/cell_container.dart | 4 +- .../grid/src/widgets/cell/checkbox_cell.dart | 2 +- .../grid/src/widgets/cell/date_cell.dart | 4 +- .../grid/src/widgets/cell/number_cell.dart | 4 +- .../cell/selection_cell/selection_cell.dart | 8 +- .../cell/selection_cell/selection_editor.dart | 4 +- .../grid/src/widgets/cell/text_cell.dart | 4 +- .../src/widgets/row/cell/number_cell.dart | 2 +- .../grid/src/widgets/row/number_cell.dart | 2 +- 23 files changed, 186 insertions(+), 174 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 13eeae9033..2fd03d639f 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -168,32 +168,32 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => TextCellBloc( service: CellService(), cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => SelectionCellBloc( cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => NumberCellBloc( cellData: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => DateCellBloc( cellIdentifier: cellData, ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (cellData, _) => CheckboxCellBloc( service: CellService(), cellData: cellData, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart index a4a3cf2d60..dce064eae2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart @@ -44,7 +44,7 @@ class CellCache { CellCache() : _cellService = CellService(); - Future> getCellData(GridCellIdentifier identifier) async { + Future> getCellData(GridCell identifier) async { final cellId = _cellId(identifier); final Cell? data = _cellDataMap[cellId]; if (data != null) { @@ -69,7 +69,7 @@ class CellCache { ); } - String _cellId(GridCellIdentifier identifier) { + String _cellId(GridCell identifier) { return "${identifier.rowId}/${identifier.field.id}"; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart index 2fae2464be..6d2935458a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart @@ -15,7 +15,7 @@ class CheckboxCellBloc extends Bloc { CheckboxCellBloc({ required CellService service, - required GridCellIdentifier cellData, + required GridCell cellData, }) : _service = service, _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(CheckboxCellState.initial(cellData)) { @@ -87,11 +87,11 @@ class CheckboxCellEvent with _$CheckboxCellEvent { @freezed class CheckboxCellState with _$CheckboxCellState { const factory CheckboxCellState({ - required GridCellIdentifier cellData, + required GridCell cellData, required bool isSelected, }) = _CheckboxCellState; - factory CheckboxCellState.initial(GridCellIdentifier cellData) { + factory CheckboxCellState.initial(GridCell cellData) { return CheckboxCellState(cellData: cellData, isSelected: _isSelected(cellData.cell)); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart index e4c94230a9..532b67ae3a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart @@ -15,7 +15,7 @@ class DateCellBloc extends Bloc { final CellListener _cellListener; final SingleFieldListener _fieldListener; - DateCellBloc({required GridCellIdentifier cellIdentifier}) + DateCellBloc({required GridCell cellIdentifier}) : _service = CellService(), _cellListener = CellListener(rowId: cellIdentifier.rowId, fieldId: cellIdentifier.field.id), _fieldListener = SingleFieldListener(fieldId: cellIdentifier.field.id), @@ -106,13 +106,13 @@ class DateCellEvent with _$DateCellEvent { @freezed class DateCellState with _$DateCellState { const factory DateCellState({ - required GridCellIdentifier cellData, + required GridCell cellData, required String content, required Field field, DateTime? selectedDay, }) = _DateCellState; - factory DateCellState.initial(GridCellIdentifier cellData) => DateCellState( + factory DateCellState.initial(GridCell cellData) => DateCellState( cellData: cellData, field: cellData.field, content: cellData.cell?.content ?? "", diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart index 531e06062a..27f17257e1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart @@ -16,7 +16,7 @@ class NumberCellBloc extends Bloc { final SingleFieldListener _fieldListener; NumberCellBloc({ - required GridCellIdentifier cellData, + required GridCell cellData, }) : _service = CellService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), _fieldListener = SingleFieldListener(fieldId: cellData.field.id), @@ -105,11 +105,11 @@ class NumberCellEvent with _$NumberCellEvent { @freezed class NumberCellState with _$NumberCellState { const factory NumberCellState({ - required GridCellIdentifier cellData, + required GridCell cellData, required String content, }) = _NumberCellState; - factory NumberCellState.initial(GridCellIdentifier cellData) { + factory NumberCellState.initial(GridCell cellData) { return NumberCellState(cellData: cellData, content: cellData.cell?.content ?? ""); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart index 95ccedd086..2d7435dc7a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_cell_bloc.dart @@ -16,7 +16,7 @@ class SelectionCellBloc extends Bloc { final SingleFieldListener _fieldListener; SelectionCellBloc({ - required GridCellIdentifier cellData, + required GridCell cellData, }) : _service = SelectOptionService(), _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), _fieldListener = SingleFieldListener(fieldId: cellData.field.id), @@ -93,12 +93,12 @@ class SelectionCellEvent with _$SelectionCellEvent { @freezed class SelectionCellState with _$SelectionCellState { const factory SelectionCellState({ - required GridCellIdentifier cellData, + required GridCell cellData, required List options, required List selectedOptions, }) = _SelectionCellState; - factory SelectionCellState.initial(GridCellIdentifier cellData) => SelectionCellState( + factory SelectionCellState.initial(GridCell cellData) => SelectionCellState( cellData: cellData, options: [], selectedOptions: [], diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart index 1636c293ed..92676a0c12 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart @@ -18,7 +18,7 @@ class SelectOptionEditorBloc extends Bloc options, required List selectedOptions, }) : _selectOptionService = SelectOptionService(), @@ -174,7 +174,7 @@ class SelectOptionEditorState with _$SelectOptionEditorState { }) = _SelectOptionEditorState; factory SelectOptionEditorState.initial( - GridCellIdentifier cellData, + GridCell cellData, List options, List selectedOptions, ) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart index e45cb7c1f1..ec78136dd3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart @@ -11,7 +11,7 @@ class TextCellBloc extends Bloc { TextCellBloc({ required this.service, - required GridCellIdentifier cellData, + required GridCell cellData, }) : super(TextCellState.initial(cellData)) { on( (event, emit) async { @@ -53,7 +53,7 @@ class TextCellBloc extends Bloc { @freezed class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; - const factory TextCellEvent.didReceiveCellData(GridCellIdentifier cellData) = _DidReceiveCellData; + const factory TextCellEvent.didReceiveCellData(GridCell cellData) = _DidReceiveCellData; const factory TextCellEvent.updateText(String text) = _UpdateText; } @@ -61,10 +61,10 @@ class TextCellEvent with _$TextCellEvent { class TextCellState with _$TextCellState { const factory TextCellState({ required String content, - required GridCellIdentifier cellData, + required GridCell cellData, }) = _TextCellState; - factory TextCellState.initial(GridCellIdentifier cellData) => TextCellState( + factory TextCellState.initial(GridCell cellData) => TextCellState( content: cellData.cell?.content ?? "", cellData: cellData, ); 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 6e19f1f3a5..93036082fb 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -13,13 +13,17 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final GridService _gridService; final GridFieldCache fieldCache; - final GridRowCache rowCache; + late final GridRowCache rowCache; GridBloc({required View view}) : _gridService = GridService(gridId: view.id), fieldCache = GridFieldCache(gridId: view.id), - rowCache = GridRowCache(gridId: view.id), super(GridState.initial(view.id)) { + rowCache = GridRowCache( + gridId: view.id, + dataDelegate: GridRowDataDelegateAdaptor(fieldCache), + ); + on( (event, emit) async { await event.map( @@ -77,7 +81,7 @@ class GridBloc extends Bloc { () => result.fold( (fields) { fieldCache.fields = fields.items; - rowCache.updateWithBlock(grid.blockOrders, fieldCache.unmodifiableFields); + rowCache.updateWithBlock(grid.blockOrders); emit(state.copyWith( grid: Some(grid), 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 080d6e79fc..aee2a82be4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -8,6 +8,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'row/row_service.dart'; + class GridService { final String gridId; GridService({ @@ -152,3 +154,44 @@ class GridFieldCache { _fieldNotifier.fields = fields; } } + +class GridRowDataDelegateAdaptor extends GridRowDataDelegate { + final GridFieldCache _cache; + + GridRowDataDelegateAdaptor(GridFieldCache cache) : _cache = cache; + @override + UnmodifiableListView get fields => _cache.unmodifiableFields; + + @override + GridRow buildGridRow(RowOrder rowOrder) { + return GridRow( + gridId: _cache.gridId, + fields: _cache.unmodifiableFields, + rowId: rowOrder.rowId, + height: rowOrder.height.toDouble(), + ); + } + + @override + void onFieldChanged(FieldDidUpdateCallback callback) { + _cache.addListener(listener: () { + callback(); + }); + } + + @override + CellDataMap buildCellDataMap(Row rowData) { + var map = CellDataMap.new(); + for (final field in fields) { + if (field.visibility) { + map[field.id] = GridCell( + rowId: rowData.id, + gridId: _cache.gridId, + cell: rowData.cellByFieldId[field.id], + field: field, + ); + } + } + return map; + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 5de5bcd4ab..b49485c16b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,7 +1,4 @@ import 'dart:collection'; - -import 'package:app_flowy/workspace/application/grid/grid_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -10,21 +7,15 @@ import 'package:dartz/dartz.dart'; part 'row_bloc.freezed.dart'; -typedef CellDataMap = LinkedHashMap; - class RowBloc extends Bloc { final RowService _rowService; - final GridFieldCache _fieldCache; final GridRowCache _rowCache; - void Function()? _rowListenCallback; - void Function()? _fieldListenCallback; + void Function()? _rowListenFn; RowBloc({ required GridRow rowData, - required GridFieldCache fieldCache, required GridRowCache rowCache, }) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId), - _fieldCache = fieldCache, _rowCache = rowCache, super(RowState.initial(rowData)) { on( @@ -37,92 +28,45 @@ class RowBloc extends Bloc { createRow: (_CreateRow value) { _rowService.createRow(); }, - didUpdateRow: (_DidUpdateRow value) async { - _handleRowUpdate(value.row, emit); - }, - fieldsDidUpdate: (_FieldsDidUpdate value) async { - await _handleFieldUpdate(emit); - }, - didLoadRow: (_DidLoadRow value) { - _handleRowUpdate(value.row, emit); + didReceiveCellDatas: (_DidReceiveCellDatas value) async { + emit(state.copyWith(cellDataMap: Some(value.cellData))); }, ); }, ); } - void _handleRowUpdate(Row row, Emitter emit) { - final CellDataMap cellDataMap = _makeCellDatas(row, state.rowData.fields); - emit(state.copyWith(cellDataMap: Some(cellDataMap))); - } - - Future _handleFieldUpdate(Emitter emit) async { - final data = state.rowData.data; - if (data == null) { - return; - } - - final CellDataMap cellDataMap = _makeCellDatas(data, state.rowData.fields); - emit(state.copyWith(cellDataMap: Some(cellDataMap))); - } - @override Future close() async { - if (_rowListenCallback != null) { - _rowCache.removeRowListener(_rowListenCallback!); - } - - if (_fieldListenCallback != null) { - _fieldCache.removeListener(_fieldListenCallback!); + if (_rowListenFn != null) { + _rowCache.removeRowListener(_rowListenFn!); } return super.close(); } Future _startListening() async { - _fieldListenCallback = _fieldCache.addListener( - listener: () => add(const RowEvent.fieldsDidUpdate()), - listenWhen: () => !isClosed, - ); - - _rowListenCallback = _rowCache.addRowListener( + _rowListenFn = _rowCache.addRowListener( rowId: state.rowData.rowId, - onUpdated: (row) => add(RowEvent.didUpdateRow(row)), + onUpdated: (cellDatas) => add(RowEvent.didReceiveCellDatas(cellDatas)), listenWhen: () => !isClosed, ); } Future _loadRow(Emitter emit) async { - final data = _rowCache.loadRow(state.rowData.rowId); - data.foldRight(null, (data, _) { + final data = _rowCache.loadCellData(state.rowData.rowId); + data.foldRight(null, (cellDatas, _) { if (!isClosed) { - add(RowEvent.didLoadRow(data)); + add(RowEvent.didReceiveCellDatas(cellDatas)); } }); } - - CellDataMap _makeCellDatas(Row row, List fields) { - var map = CellDataMap.new(); - for (final field in fields) { - if (field.visibility) { - map[field.id] = GridCellIdentifier( - rowId: row.id, - gridId: _rowService.gridId, - cell: row.cellByFieldId[field.id], - field: field, - ); - } - } - return map; - } } @freezed class RowEvent with _$RowEvent { const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; - const factory RowEvent.fieldsDidUpdate() = _FieldsDidUpdate; - const factory RowEvent.didLoadRow(Row row) = _DidLoadRow; - const factory RowEvent.didUpdateRow(Row row) = _DidUpdateRow; + const factory RowEvent.didReceiveCellDatas(CellDataMap cellData) = _DidReceiveCellDatas; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index d1b77f84e9..63129f4015 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -8,31 +8,36 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; - import 'package:app_flowy/workspace/application/grid/grid_listener.dart'; - part 'row_service.freezed.dart'; +typedef RowUpdateCallback = void Function(); +typedef FieldDidUpdateCallback = void Function(); +typedef CellDataMap = LinkedHashMap; + +abstract class GridRowDataDelegate { + UnmodifiableListView get fields; + GridRow buildGridRow(RowOrder rowOrder); + CellDataMap buildCellDataMap(Row rowData); + void onFieldChanged(FieldDidUpdateCallback callback); +} + class GridRowCache { final String gridId; + final RowsNotifier _rowNotifier; final GridRowListener _rowsListener; - late final _RowsNotifier _rowNotifier; - UnmodifiableListView _fields = UnmodifiableListView([]); + final GridRowDataDelegate _dataDelegate; List get clonedRows => _rowNotifier.clonedRows; - GridRowCache({required this.gridId}) : _rowsListener = GridRowListener(gridId: gridId) { - _rowNotifier = _RowsNotifier( - rowBuilder: (rowOrder) { - return GridRow( - gridId: gridId, - fields: _fields, - rowId: rowOrder.rowId, - height: rowOrder.height.toDouble(), - ); - }, - ); + GridRowCache({required this.gridId, required GridRowDataDelegate dataDelegate}) + : _rowNotifier = RowsNotifier(rowBuilder: dataDelegate.buildGridRow), + _rowsListener = GridRowListener(gridId: gridId), + _dataDelegate = dataDelegate { + // + dataDelegate.onFieldChanged(() => _rowNotifier.fieldDidChange()); + // listen on the row update _rowsListener.rowsUpdateNotifier.addPublishListener((result) { result.fold( (changesets) { @@ -68,9 +73,9 @@ class GridRowCache { }); } - VoidCallback addRowListener({ + RowUpdateCallback addRowListener({ required String rowId, - void Function(Row)? onUpdated, + void Function(CellDataMap)? onUpdated, bool Function()? listenWhen, }) { listenrHandler() { @@ -82,12 +87,22 @@ class GridRowCache { return; } - _rowNotifier._changeReason.whenOrNull(update: (indexs) { + notify() { final row = _rowNotifier.rowDataWithId(rowId); - if (indexs[rowId] != null && row != null) { - onUpdated(row); + if (row != null) { + final cellDataMap = _dataDelegate.buildCellDataMap(row); + onUpdated(cellDataMap); } - }); + } + + _rowNotifier._changeReason.whenOrNull( + update: (indexs) { + if (indexs[rowId] != null) { + notify(); + } + }, + fieldDidChange: () => notify(), + ); } _rowNotifier.addListener(listenrHandler); @@ -98,10 +113,10 @@ class GridRowCache { _rowNotifier.removeListener(callback); } - Option loadRow(String rowId) { + Option loadCellData(String rowId) { final Row? data = _rowNotifier.rowDataWithId(rowId); if (data != null) { - return Some(data); + return Some(_dataDelegate.buildCellDataMap(data)); } final payload = RowIdentifierPayload.create() @@ -117,8 +132,7 @@ class GridRowCache { return none(); } - void updateWithBlock(List blocks, UnmodifiableListView fields) { - _fields = fields; + void updateWithBlock(List blocks) { final rowOrders = blocks.expand((block) => block.rowOrders).toList(); _rowNotifier.reset(rowOrders); } @@ -136,13 +150,13 @@ class GridRowCache { } } -class _RowsNotifier extends ChangeNotifier { +class RowsNotifier extends ChangeNotifier { List _rows = []; HashMap _rowDataMap = HashMap(); GridRowChangeReason _changeReason = const InitialListState(); final GridRow Function(RowOrder) rowBuilder; - _RowsNotifier({ + RowsNotifier({ required this.rowBuilder, }); @@ -199,9 +213,10 @@ class _RowsNotifier extends ChangeNotifier { final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); if (index != -1) { newRows.removeAt(index); - // Remove the cache data + // Remove the old row data, the data will be filled if the loadRow method gets called. _rowDataMap.remove(rowOrder.rowId); newRows.insert(index, rowBuilder(rowOrder)); + updatedIndexs[rowOrder.rowId] = UpdatedIndex(index: index, rowId: rowOrder.rowId); } } @@ -209,14 +224,19 @@ class _RowsNotifier extends ChangeNotifier { _update(newRows, GridRowChangeReason.update(updatedIndexs)); } - void _update(List rows, GridRowChangeReason changeReason) { - _rows = rows; - _changeReason = changeReason; + void fieldDidChange() { + _update(_rows, const GridRowChangeReason.fieldDidChange()); + } - changeReason.map( + void _update(List rows, GridRowChangeReason reason) { + _rows = rows; + _changeReason = reason; + + _changeReason.map( insert: (_) => notifyListeners(), delete: (_) => notifyListeners(), update: (_) => notifyListeners(), + fieldDidChange: (_) => notifyListeners(), initial: (_) {}, ); } @@ -227,13 +247,17 @@ class _RowsNotifier extends ChangeNotifier { _rowDataMap[rowData.id] = rowData; final index = _rows.indexWhere((row) => row.rowId == rowData.id); if (index != -1) { + // update the corresponding row in _rows if they are not the same if (_rows[index].data != rowData) { final row = _rows.removeAt(index).copyWith(data: rowData); _rows.insert(index, row); + // Calculate the update index final UpdatedIndexs updatedIndexs = UpdatedIndexs(); updatedIndexs[row.rowId] = UpdatedIndex(index: index, rowId: row.rowId); _changeReason = GridRowChangeReason.update(updatedIndexs); + + // notifyListeners(); } } @@ -296,16 +320,6 @@ class RowService { } } -@freezed -class GridCellIdentifier with _$GridCellIdentifier { - const factory GridCellIdentifier({ - required String gridId, - required String rowId, - required Field field, - Cell? cell, - }) = _GridCellIdentifier; -} - @freezed class GridRow with _$GridRow { const factory GridRow({ @@ -317,13 +331,32 @@ class GridRow with _$GridRow { }) = _GridRow; } +@freezed +class GridCell with _$GridCell { + const factory GridCell({ + required String gridId, + required String rowId, + required Field field, + Cell? cell, + }) = _GridCell; +} + typedef InsertedIndexs = List; typedef DeletedIndexs = List; typedef UpdatedIndexs = LinkedHashMap; +@freezed +class GridRowChangeReason with _$GridRowChangeReason { + const factory GridRowChangeReason.insert(InsertedIndexs items) = _Insert; + const factory GridRowChangeReason.delete(DeletedIndexs items) = _Delete; + const factory GridRowChangeReason.update(UpdatedIndexs indexs) = _Update; + const factory GridRowChangeReason.fieldDidChange() = _FieldDidChange; + const factory GridRowChangeReason.initial() = InitialListState; +} + class InsertedIndex { - int index; - String rowId; + final int index; + final String rowId; InsertedIndex({ required this.index, required this.rowId, @@ -331,8 +364,8 @@ class InsertedIndex { } class DeletedIndex { - int index; - GridRow row; + final int index; + final GridRow row; DeletedIndex({ required this.index, required this.row, @@ -340,18 +373,10 @@ class DeletedIndex { } class UpdatedIndex { - int index; - String rowId; + final int index; + final String rowId; UpdatedIndex({ required this.index, required this.rowId, }); } - -@freezed -class GridRowChangeReason with _$GridRowChangeReason { - const factory GridRowChangeReason.insert(InsertedIndexs items) = _Insert; - const factory GridRowChangeReason.delete(DeletedIndexs items) = _Delete; - const factory GridRowChangeReason.update(UpdatedIndexs indexs) = _Update; - const factory GridRowChangeReason.initial() = InitialListState; -} 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 3303cde961..12b9f8963f 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 @@ -227,16 +227,12 @@ class _GridRowsState extends State<_GridRows> { GridRow rowData, Animation animation, ) { - final bloc = context.read(); - final fieldCache = bloc.fieldCache; - final rowCache = bloc.rowCache; - + final rowCache = context.read().rowCache; return SizeTransition( sizeFactor: animation, child: GridRowWidget( blocBuilder: () => RowBloc( rowData: rowData, - fieldCache: fieldCache, rowCache: rowCache, ), key: ValueKey(rowData.rowId), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 7af09ca6b5..94f2e0da70 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -7,7 +7,7 @@ import 'number_cell.dart'; import 'selection_cell/selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(GridCellIdentifier cellData) { +Widget buildGridCell(GridCell cellData) { final key = ValueKey(cellData.field.id + cellData.rowId); switch (cellData.field.fieldType) { case FieldType.Checkbox: diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index c9af10c2b8..e49928f7ac 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -55,8 +55,8 @@ class CellContainer extends StatelessWidget { } } -abstract class GridCell extends StatefulWidget { - const GridCell({Key? key}) : super(key: key); +abstract class GridCellWidget extends StatefulWidget { + const GridCellWidget({Key? key}) : super(key: key); void setFocus(BuildContext context, bool value) { Provider.of(context, listen: false).isFocus = value; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index 312c8ef71c..cbf8d0fadb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final GridCellIdentifier cellData; + final GridCell cellData; const CheckboxCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index 33f99c2386..dcd2b2f5c2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -8,8 +8,8 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:table_calendar/table_calendar.dart'; -class DateCell extends GridCell { - final GridCellIdentifier cellData; +class DateCell extends GridCellWidget { + final GridCell cellData; const DateCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index 56946945ae..09331e49b5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -6,8 +6,8 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/c import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class NumberCell extends GridCell { - final GridCellIdentifier cellData; +class NumberCell extends GridCellWidget { + final GridCell cellData; const NumberCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 15a7813397..1261a4e5f4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -7,8 +7,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'extension.dart'; import 'selection_editor.dart'; -class SingleSelectCell extends GridCell { - final GridCellIdentifier cellData; +class SingleSelectCell extends GridCellWidget { + final GridCell cellData; const SingleSelectCell({ required this.cellData, @@ -63,8 +63,8 @@ class _SingleSelectCellState extends State { } //---------------------------------------------------------------- -class MultiSelectCell extends GridCell { - final GridCellIdentifier cellData; +class MultiSelectCell extends GridCellWidget { + final GridCell cellData; const MultiSelectCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index e3e0b39f0a..d3fcd9efcf 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -25,7 +25,7 @@ import 'text_field.dart'; const double _editorPannelWidth = 300; class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { - final GridCellIdentifier cellData; + final GridCell cellData; final List options; final List selectedOptions; final VoidCallback onDismissed; @@ -66,7 +66,7 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { static void show( BuildContext context, - GridCellIdentifier cellData, + GridCell cellData, List options, List selectedOptions, VoidCallback onDismissed, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index e6649853a5..93fb4b15e7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -5,8 +5,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_container.dart'; -class GridTextCell extends GridCell { - final GridCellIdentifier cellData; +class GridTextCell extends GridCellWidget { + final GridCell cellData; const GridTextCell({ required this.cellData, Key? key, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart index 6e4c430986..0f3f7c5f32 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/cell/number_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final GridCellIdentifier cellData; + final GridCell cellData; const NumberCell({ required this.cellData, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart index 6e4c430986..0f3f7c5f32 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/number_cell.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final GridCellIdentifier cellData; + final GridCell cellData; const NumberCell({ required this.cellData, From eeba6884ce309479e3a49c6d73f4512ee7c3b636 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 20 Apr 2022 16:32:12 +0800 Subject: [PATCH 175/179] chore: config row detail page --- .../app_flowy/assets/images/grid/expander.svg | 6 + .../application/grid/row/row_detail_bloc.dart | 73 +++++++ .../application/grid/row/row_service.dart | 44 ++-- .../plugins/grid/src/grid_page.dart | 6 +- .../grid/src/widgets/cell/cell_container.dart | 60 +++++- .../header/field_cell_action_sheet.dart | 44 ++-- .../grid/src/widgets/row/grid_row.dart | 150 +++++++++---- .../grid/src/widgets/row/row_detail.dart | 48 +++++ .../src/widgets/toolbar/grid_property.dart | 2 +- .../flowy-grid-data-model/grid.pb.dart | 14 ++ .../flowy-grid-data-model/grid.pbjson.dart | 3 +- .../src/services/field/field_builder.rs | 8 +- .../flowy-grid/src/services/grid_editor.rs | 5 +- frontend/rust-lib/flowy-grid/src/util.rs | 1 + .../rust-lib/flowy-grid/tests/grid/script.rs | 2 + .../src/entities/grid.rs | 4 + .../src/entities/meta.rs | 13 +- .../src/protobuf/model/grid.rs | 202 +++++++++++------- .../src/protobuf/proto/grid.proto | 1 + .../src/client_grid/grid_builder.rs | 4 +- 20 files changed, 506 insertions(+), 184 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/expander.svg create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart diff --git a/frontend/app_flowy/assets/images/grid/expander.svg b/frontend/app_flowy/assets/images/grid/expander.svg new file mode 100644 index 0000000000..179bdb1a9e --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/expander.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart new file mode 100644 index 0000000000..e93f0be89b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart @@ -0,0 +1,73 @@ +import 'dart:collection'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'row_service.dart'; +import 'package:dartz/dartz.dart'; + +part 'row_detail_bloc.freezed.dart'; + +class RowDetailBloc extends Bloc { + final GridRow rowData; + final GridRowCache _rowCache; + void Function()? _rowListenFn; + + RowDetailBloc({ + required this.rowData, + required GridRowCache rowCache, + }) : _rowCache = rowCache, + super(RowDetailState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_Initial value) async { + await _startListening(); + }, + didReceiveCellDatas: (_DidReceiveCellDatas value) {}, + ); + }, + ); + } + + @override + Future close() async { + if (_rowListenFn != null) { + _rowCache.removeRowListener(_rowListenFn!); + } + return super.close(); + } + + Future _startListening() async { + _rowListenFn = _rowCache.addRowListener( + rowId: rowData.rowId, + onUpdated: (cellDatas) => add(RowDetailEvent.didReceiveCellDatas(cellDatas)), + listenWhen: () => !isClosed, + ); + } + + Future _loadRow(Emitter emit) async { + final data = _rowCache.loadCellData(rowData.rowId); + data.foldRight(null, (cellDatas, _) { + if (!isClosed) { + add(RowDetailEvent.didReceiveCellDatas(cellDatas)); + } + }); + } +} + +@freezed +class RowDetailEvent with _$RowDetailEvent { + const factory RowDetailEvent.initial() = _Initial; + const factory RowDetailEvent.didReceiveCellDatas(CellDataMap cellData) = _DidReceiveCellDatas; +} + +@freezed +class RowDetailState with _$RowDetailState { + const factory RowDetailState({ + required Option cellDataMap, + }) = _RowDetailState; + + factory RowDetailState.initial() => RowDetailState( + cellDataMap: none(), + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 63129f4015..f524e03d0c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -42,9 +42,9 @@ class GridRowCache { result.fold( (changesets) { for (final changeset in changesets) { - _deleteRows(changeset.deletedRows); - _insertRows(changeset.insertedRows); - _updateRows(changeset.updatedRows); + _rowNotifier.deleteRows(changeset.deletedRows); + _rowNotifier.insertRows(changeset.insertedRows); + _rowNotifier.updateRows(changeset.updatedRows); } }, (err) => Log.error(err), @@ -63,13 +63,15 @@ class GridRowCache { bool Function()? listenWhen, }) { _rowNotifier.addListener(() { + if (onChanged == null) { + return; + } + if (listenWhen != null && listenWhen() == false) { return; } - if (onChanged != null) { - onChanged(clonedRows, _rowNotifier._changeReason); - } + onChanged(clonedRows, _rowNotifier._changeReason); }); } @@ -136,18 +138,6 @@ class GridRowCache { final rowOrders = blocks.expand((block) => block.rowOrders).toList(); _rowNotifier.reset(rowOrders); } - - void _deleteRows(List deletedRows) { - _rowNotifier.deleteRows(deletedRows); - } - - void _insertRows(List createdRows) { - _rowNotifier.insertRows(createdRows); - } - - void _updateRows(List rowOrders) { - _rowNotifier.updateRows(rowOrders); - } } class RowsNotifier extends ChangeNotifier { @@ -173,7 +163,7 @@ class RowsNotifier extends ChangeNotifier { final List newRows = []; final DeletedIndexs deletedIndex = []; - final Map deletedRowMap = {for (var rowOrder in deletedRows) rowOrder.rowId: rowOrder}; + final Map deletedRowMap = {for (var e in deletedRows) e.rowId: e}; _rows.asMap().forEach((index, row) { if (deletedRowMap[row.rowId] == null) { @@ -192,12 +182,14 @@ class RowsNotifier extends ChangeNotifier { } InsertedIndexs insertIndexs = []; - final List newRows = _rows; + final List newRows = clonedRows; for (final createdRow in createdRows) { - final rowOrder = createdRow.rowOrder; - final insertIndex = InsertedIndex(index: createdRow.index, rowId: rowOrder.rowId); + final insertIndex = InsertedIndex( + index: createdRow.index, + rowId: createdRow.rowOrder.rowId, + ); insertIndexs.add(insertIndex); - newRows.insert(createdRow.index, (rowBuilder(rowOrder))); + newRows.insert(createdRow.index, (rowBuilder(createdRow.rowOrder))); } _update(newRows, GridRowChangeReason.insert(insertIndexs)); } @@ -208,15 +200,15 @@ class RowsNotifier extends ChangeNotifier { } final UpdatedIndexs updatedIndexs = UpdatedIndexs(); - final List newRows = _rows; + final List newRows = clonedRows; for (final rowOrder in updatedRows) { final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); if (index != -1) { - newRows.removeAt(index); // Remove the old row data, the data will be filled if the loadRow method gets called. _rowDataMap.remove(rowOrder.rowId); - newRows.insert(index, rowBuilder(rowOrder)); + newRows.removeAt(index); + newRows.insert(index, rowBuilder(rowOrder)); updatedIndexs[rowOrder.rowId] = UpdatedIndex(index: index, rowId: rowOrder.rowId); } } 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 12b9f8963f..b3d35977b8 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 @@ -231,10 +231,8 @@ class _GridRowsState extends State<_GridRows> { return SizeTransition( sizeFactor: animation, child: GridRowWidget( - blocBuilder: () => RowBloc( - rowData: rowData, - rowCache: rowCache, - ), + rowData: rowData, + rowCache: rowCache, key: ValueKey(rowData.rowId), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index e49928f7ac..243edae3a9 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -6,6 +6,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d class CellStateNotifier extends ChangeNotifier { bool _isFocus = false; + bool _onEnter = false; set isFocus(bool value) { if (_isFocus != value) { @@ -14,38 +15,56 @@ class CellStateNotifier extends ChangeNotifier { } } + set onEnter(bool value) { + if (_onEnter != value) { + _onEnter = value; + notifyListeners(); + } + } + bool get isFocus => _isFocus; + + bool get onEnter => _onEnter; } class CellContainer extends StatelessWidget { final Widget child; + final Widget? expander; final double width; const CellContainer({ Key? key, required this.child, required this.width, + this.expander, }) : super(key: key); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => CellStateNotifier(), - child: Consumer( - builder: (context, state, _) { + child: Selector( + selector: (context, notifier) => notifier.isFocus, + builder: (context, isFocus, _) { + Widget container = Center(child: child); + + if (expander != null) { + container = _CellEnterRegion(child: container, expander: expander!); + } + return Container( constraints: BoxConstraints(maxWidth: width), - decoration: _makeBoxDecoration(context, state), + decoration: _makeBoxDecoration(context, isFocus), padding: GridSize.cellContentInsets, - child: Center(child: child), + child: container, ); }, ), ); } - BoxDecoration _makeBoxDecoration(BuildContext context, CellStateNotifier state) { + BoxDecoration _makeBoxDecoration(BuildContext context, bool isFocus) { final theme = context.watch(); - if (state.isFocus) { + if (isFocus) { final borderSide = BorderSide(color: theme.main1, width: 1.0); return BoxDecoration(border: Border.fromBorderSide(borderSide)); } else { @@ -55,6 +74,35 @@ class CellContainer extends StatelessWidget { } } +class _CellEnterRegion extends StatelessWidget { + final Widget expander; + final Widget child; + const _CellEnterRegion({required this.expander, required this.child, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Selector( + selector: (context, notifier) => notifier.onEnter, + builder: (context, onEnter, _) { + List children = [child]; + if (onEnter) { + children.add(expander); + } + + return MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => Provider.of(context, listen: false).onEnter = true, + onExit: (p) => Provider.of(context, listen: false).onEnter = false, + child: Stack( + alignment: AlignmentDirectional.centerEnd, + children: children, + ), + ); + }, + ); + } +} + abstract class GridCellWidget extends StatefulWidget { const GridCellWidget({Key? key}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart index 2dc1e2976b..3e7f0c9271 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell_action_sheet.dart @@ -90,16 +90,6 @@ class _FieldOperationList extends StatelessWidget { @override Widget build(BuildContext context) { - final actions = FieldAction.values - .map( - (action) => FieldActionCell( - fieldId: fieldData.field.id, - action: action, - onTap: onDismissed, - ), - ) - .toList(); - return GridView( // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html shrinkWrap: true, @@ -108,20 +98,44 @@ class _FieldOperationList extends StatelessWidget { childAspectRatio: 4.0, mainAxisSpacing: 8, ), - children: actions, + children: buildCells(), ); } + + List buildCells() { + return FieldAction.values.map( + (action) { + bool enable = true; + switch (action) { + case FieldAction.delete: + enable = !fieldData.field.isPrimary; + break; + default: + break; + } + + return FieldActionCell( + fieldId: fieldData.field.id, + action: action, + onTap: onDismissed, + enable: enable, + ); + }, + ).toList(); + } } class FieldActionCell extends StatelessWidget { final String fieldId; final VoidCallback onTap; final FieldAction action; + final bool enable; const FieldActionCell({ required this.fieldId, required this.action, required this.onTap, + required this.enable, Key? key, }) : super(key: key); @@ -129,11 +143,13 @@ class FieldActionCell extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( - text: FlowyText.medium(action.title(), fontSize: 12), + text: FlowyText.medium(action.title(), fontSize: 12, color: enable ? null : theme.shader4), hoverColor: theme.hover, onTap: () { - action.run(context); - onTap(); + if (enable) { + action.run(context); + onTap(); + } }, leftIcon: svgWidget(action.iconName(), color: theme.iconColor), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 316b5ec9c0..5c08bab8c8 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -8,12 +8,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; import 'row_action_sheet.dart'; +import 'package:dartz/dartz.dart' show Option; + +import 'row_detail.dart'; class GridRowWidget extends StatefulWidget { - final RowBloc Function() blocBuilder; + final GridRow rowData; + final GridRowCache rowCache; const GridRowWidget({ - required this.blocBuilder, + required this.rowData, + required this.rowCache, Key? key, }) : super(key: key); @@ -23,13 +28,14 @@ class GridRowWidget extends StatefulWidget { class _GridRowWidgetState extends State { late RowBloc _rowBloc; - late _RegionStateNotifier _rowStateNotifier; @override void initState() { - _rowBloc = widget.blocBuilder(); + _rowBloc = RowBloc( + rowData: widget.rowData, + rowCache: widget.rowCache, + ); _rowBloc.add(const RowEvent.initial()); - _rowStateNotifier = _RegionStateNotifier(); super.initState(); } @@ -37,29 +43,24 @@ class _GridRowWidgetState extends State { Widget build(BuildContext context) { return BlocProvider.value( value: _rowBloc, - child: ChangeNotifierProvider.value( - value: _rowStateNotifier, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => _rowStateNotifier.onEnter = true, - onExit: (p) => _rowStateNotifier.onEnter = false, - child: BlocBuilder( - buildWhen: (p, c) => p.rowData.height != c.rowData.height, - builder: (context, state) { - return SizedBox( - height: 42, - child: Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, - ), + child: _RowEnterRegion( + child: BlocBuilder( + buildWhen: (p, c) => p.rowData.height != c.rowData.height, + builder: (context, state) { + final children = [ + const _RowLeading(), + _RowCells(onExpand: () => onExpandCell(context)), + const _RowTrailing(), + ]; + + final child = Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: children, + ); + + return SizedBox(height: 42, child: child); + }, ), ), ); @@ -68,9 +69,13 @@ class _GridRowWidgetState extends State { @override Future dispose() async { _rowBloc.close(); - _rowStateNotifier.dispose(); super.dispose(); } + + void onExpandCell(BuildContext context) { + final page = RowDetailPage(rowData: widget.rowData, rowCache: widget.rowCache); + page.show(context); + } } class _RowLeading extends StatelessWidget { @@ -142,32 +147,41 @@ class _DeleteRowButton extends StatelessWidget { } class _RowCells extends StatelessWidget { - const _RowCells({Key? key}) : super(key: key); + final VoidCallback onExpand; + const _RowCells({required this.onExpand, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return BlocBuilder( buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { - final List children = state.cellDataMap.fold(() => [], _toCells); return Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, - children: children, + children: _makeCells(state.cellDataMap), ); }, ); } - List _toCells(CellDataMap dataMap) { - return dataMap.values.map( - (cellData) { - return CellContainer( - width: cellData.field.width.toDouble(), - child: buildGridCell(cellData), - ); - }, - ).toList(); + List _makeCells(Option data) { + return data.fold( + () => [], + (cellDataMap) => cellDataMap.values.map( + (cellData) { + Widget? expander; + if (cellData.field.isPrimary) { + expander = _CellExpander(onExpand: onExpand); + } + + return CellContainer( + width: cellData.field.width.toDouble(), + child: buildGridCell(cellData), + expander: expander, + ); + }, + ).toList(), + ); } } @@ -183,3 +197,57 @@ class _RegionStateNotifier extends ChangeNotifier { bool get onEnter => _onEnter; } + +class _CellExpander extends StatelessWidget { + final VoidCallback onExpand; + const _CellExpander({required this.onExpand, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyIconButton( + width: 20, + onPressed: onExpand, + iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), + icon: svgWidget("grid/expander", color: theme.main1), + ); + } +} + +class _RowEnterRegion extends StatefulWidget { + final Widget child; + const _RowEnterRegion({required this.child, Key? key}) : super(key: key); + + @override + State<_RowEnterRegion> createState() => _RowEnterRegionState(); +} + +class _RowEnterRegionState extends State<_RowEnterRegion> { + late _RegionStateNotifier _rowStateNotifier; + + @override + void initState() { + _rowStateNotifier = _RegionStateNotifier(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider.value( + value: _rowStateNotifier, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowStateNotifier.onEnter = true, + onExit: (p) => _rowStateNotifier.onEnter = false, + child: widget.child, + ), + ); + ; + } + + @override + Future dispose() async { + _rowStateNotifier.dispose(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart new file mode 100644 index 0000000000..e41a4b484b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart @@ -0,0 +1,48 @@ +import 'package:app_flowy/workspace/application/grid/row/row_detail_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:window_size/window_size.dart'; + +class RowDetailPage extends StatelessWidget with FlowyOverlayDelegate { + final GridRow rowData; + final GridRowCache rowCache; + + const RowDetailPage({ + required this.rowData, + required this.rowCache, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => RowDetailBloc(rowData: rowData, rowCache: rowCache), + child: Container(), + ); + } + + void show(BuildContext context) async { + FlowyOverlay.of(context).remove(identifier()); + + const size = Size(460, 400); + final window = await getWindowInfo(); + FlowyOverlay.of(context).insertWithRect( + widget: OverlayContainer( + child: this, + constraints: BoxConstraints.tight(const Size(460, 400)), + ), + identifier: identifier(), + anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), + anchorSize: window.frame.size, + anchorDirection: AnchorDirection.center, + style: FlowyOverlayStyle(blur: false), + delegate: this, + ); + } + + static String identifier() { + return (RowDetailPage).toString(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index bc108f78d7..aa8f88ab5d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -67,7 +67,7 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { } String identifier() { - return toString(); + return (GridPropertyList).toString(); } @override 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 8c01e7c1bc..e64431b1f9 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 @@ -85,6 +85,7 @@ class Field extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..aOB(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isPrimary') ..hasRequiredFields = false ; @@ -97,6 +98,7 @@ class Field extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, + $core.bool? isPrimary, }) { final _result = create(); if (id != null) { @@ -120,6 +122,9 @@ class Field extends $pb.GeneratedMessage { if (width != null) { _result.width = width; } + if (isPrimary != null) { + _result.isPrimary = isPrimary; + } return _result; } factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -205,6 +210,15 @@ class Field extends $pb.GeneratedMessage { $core.bool hasWidth() => $_has(6); @$pb.TagNumber(7) void clearWidth() => clearField(7); + + @$pb.TagNumber(8) + $core.bool get isPrimary => $_getBF(7); + @$pb.TagNumber(8) + set isPrimary($core.bool v) { $_setBool(7, v); } + @$pb.TagNumber(8) + $core.bool hasIsPrimary() => $_has(7); + @$pb.TagNumber(8) + void clearIsPrimary() => clearField(8); } class FieldOrder 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 624e31c392..722a8ebcd6 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 @@ -57,11 +57,12 @@ const Field$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, + const {'1': 'is_primary', '3': 8, '4': 1, '5': 8, '10': 'isPrimary'}, ], }; /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aA=='); +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIdCgppc19wcmltYXJ5GAggASgIUglpc1ByaW1hcnk='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index d20e29282e..5eaabb0294 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -13,7 +13,7 @@ pub type BoxTypeOptionBuilder = Box; impl FieldBuilder { pub fn new>(type_option_builder: T) -> Self { let type_option_builder = type_option_builder.into(); - let field_meta = FieldMeta::new("", "", type_option_builder.field_type()); + let field_meta = FieldMeta::new("", "", type_option_builder.field_type(), false); Self { field_meta, type_option_builder, @@ -35,6 +35,7 @@ impl FieldBuilder { visibility: field.visibility, width: field.width, type_options: IndexMap::default(), + is_primary: field.is_primary, }; Self { field_meta, @@ -52,6 +53,11 @@ impl FieldBuilder { self } + pub fn primary(mut self, is_primary: bool) -> Self { + self.field_meta.is_primary = is_primary; + self + } + pub fn visibility(mut self, visibility: bool) -> Self { self.field_meta.visibility = visibility; self diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 724ec65e8f..2834222778 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,9 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_manager::GridBlockMetaEditorManager; -use crate::services::entities::{CellIdentifier, CreateSelectOptionParams}; +use crate::services::entities::CellIdentifier; use crate::services::field::{ - default_type_option_builder_from_type, select_option_operation, type_option_builder_from_bytes, FieldBuilder, - SelectOption, + default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder, SelectOption, }; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 11c5f5a106..f70d685c2d 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -7,6 +7,7 @@ pub fn make_default_grid() -> BuildGridContext { let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default()) .name("Name") .visibility(true) + .primary(true) .build(); // single select diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 40ab75f780..611ee937e2 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -271,6 +271,7 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) { frozen: field_meta.frozen, visibility: field_meta.visibility, width: field_meta.width, + is_primary: false, }; let params = InsertFieldParams { @@ -303,6 +304,7 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldMet frozen: field_meta.frozen, visibility: field_meta.visibility, width: field_meta.width, + is_primary: false, }; let params = InsertFieldParams { 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 94f46919c1..d246fd490b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -42,6 +42,9 @@ pub struct Field { #[pb(index = 7)] pub width: i32, + + #[pb(index = 8)] + pub is_primary: bool, } impl std::convert::From for Field { @@ -54,6 +57,7 @@ impl std::convert::From for Field { frozen: field_meta.frozen, visibility: field_meta.visibility, width: field_meta.width, + is_primary: field_meta.is_primary, } } } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index a457ec1eb5..d5570a58e5 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -98,13 +98,21 @@ pub struct FieldMeta { // #[pb(index = 8)] /// type_options contains key/value pairs /// key: id of the FieldType - /// value: type option data string + /// value: type option data that can be parsed into specified TypeOptionStruct. + /// For example, CheckboxTypeOption, MultiSelectTypeOption etc. #[serde(with = "indexmap::serde_seq")] pub type_options: IndexMap, + + #[serde(default = "default_is_primary")] + pub is_primary: bool, +} + +fn default_is_primary() -> bool { + false } impl FieldMeta { - pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { + pub fn new(name: &str, desc: &str, field_type: FieldType, is_primary: bool) -> Self { let width = field_type.default_cell_width(); Self { id: gen_field_id(), @@ -115,6 +123,7 @@ impl FieldMeta { visibility: true, width, type_options: Default::default(), + is_primary, } } 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 d988ae90c2..754fc11386 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 @@ -290,6 +290,7 @@ pub struct Field { pub frozen: bool, pub visibility: bool, pub width: i32, + pub is_primary: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -443,6 +444,21 @@ impl Field { pub fn set_width(&mut self, v: i32) { self.width = v; } + + // bool is_primary = 8; + + + pub fn get_is_primary(&self) -> bool { + self.is_primary + } + pub fn clear_is_primary(&mut self) { + self.is_primary = false; + } + + // Param is passed by value, moved + pub fn set_is_primary(&mut self, v: bool) { + self.is_primary = v; + } } impl ::protobuf::Message for Field { @@ -487,6 +503,13 @@ impl ::protobuf::Message for Field { let tmp = is.read_int32()?; self.width = tmp; }, + 8 => { + 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_primary = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -520,6 +543,9 @@ impl ::protobuf::Message for Field { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } + if self.is_primary != false { + my_size += 2; + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -547,6 +573,9 @@ impl ::protobuf::Message for Field { if self.width != 0 { os.write_int32(7, self.width)?; } + if self.is_primary != false { + os.write_bool(8, self.is_primary)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -620,6 +649,11 @@ impl ::protobuf::Message for Field { |m: &Field| { &m.width }, |m: &mut Field| { &mut m.width }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "is_primary", + |m: &Field| { &m.is_primary }, + |m: &mut Field| { &mut m.is_primary }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Field", fields, @@ -643,6 +677,7 @@ impl ::protobuf::Clear for Field { self.frozen = false; self.visibility = false; self.width = 0; + self.is_primary = false; self.unknown_fields.clear(); } } @@ -7770,93 +7805,94 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\ngrid.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ \x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrderR\x0bfieldOr\ ders\x122\n\x0cblock_orders\x18\x03\x20\x03(\x0b2\x0f.GridBlockOrderR\ - \x0bblockOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x0bblockOrders\"\xd7\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ - id\x18\x01\x20\x01(\tR\x07fieldId\"\xc6\x01\n\x12GridFieldChangeset\x12\ - \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x124\n\x0finserted_field\ - s\x18\x02\x20\x03(\x0b2\x0b.IndexFieldR\x0einsertedFields\x122\n\x0edele\ - ted_fields\x18\x03\x20\x03(\x0b2\x0b.FieldOrderR\rdeletedFields\x12-\n\ - \x0eupdated_fields\x18\x04\x20\x03(\x0b2\x06.FieldR\rupdatedFields\"@\n\ - \nIndexField\x12\x1c\n\x05field\x18\x01\x20\x01(\x0b2\x06.FieldR\x05fiel\ - d\x12\x14\n\x05index\x18\x02\x20\x01(\x05R\x05index\"\x90\x01\n\x1aGetEd\ - itFieldContextPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x12\x1b\n\x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_t\ - ype\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field\ - _id\"q\n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\n\ - field_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFie\ - ldContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngri\ - d_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_optio\ - n_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\ - \x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Repeat\ - edFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05it\ - ems\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06heigh\ - t\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\ - \x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\ - \x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\ - \x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\ - .CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\ - \x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\ - items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\ - \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\ - \x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"_\n\rIndexRowOrder\x12&\n\ - \trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrder\x12\x16\n\x05i\ - ndex\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_index\"\xbf\x01\ - \n\x11GridRowsChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blo\ - ckId\x123\n\rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0ci\ - nsertedRows\x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0b\ - deletedRows\x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0b\ - updatedRows\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\ - \x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\ - \x07content\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificati\ - onData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08f\ - ield_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\ - \x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07content\ - B\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\ - \x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\ - \n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05va\ - lue\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\ - \x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\ - _id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\ - \x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12Ins\ - ertFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ - \x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type\ - _option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_fie\ - ld_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_fiel\ - d_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFiel\ - dOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_\ - id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\ - \x0b2\x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPa\ - yload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07\ - grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\ - \tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\ - \nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\ - \n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\ - \x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\ - \x01(\x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\ - \x06R\x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\ - \x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\ - \x0e\n\x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0f\ - MoveItemPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ - \x17\n\x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\ - \x18\x03\x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\ - \x05R\x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\ - \x02ty\"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\ - \x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\ - \x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\ - \tMoveField\x10\0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\ - \x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\ - \x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\ - \x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + idth\x18\x07\x20\x01(\x05R\x05width\x12\x1d\n\nis_primary\x18\x08\x20\ + \x01(\x08R\tisPrimary\"'\n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\ + \x01(\tR\x07fieldId\"\xc6\x01\n\x12GridFieldChangeset\x12\x17\n\x07grid_\ + id\x18\x01\x20\x01(\tR\x06gridId\x124\n\x0finserted_fields\x18\x02\x20\ + \x03(\x0b2\x0b.IndexFieldR\x0einsertedFields\x122\n\x0edeleted_fields\ + \x18\x03\x20\x03(\x0b2\x0b.FieldOrderR\rdeletedFields\x12-\n\x0eupdated_\ + fields\x18\x04\x20\x03(\x0b2\x06.FieldR\rupdatedFields\"@\n\nIndexField\ + \x12\x1c\n\x05field\x18\x01\x20\x01(\x0b2\x06.FieldR\x05field\x12\x14\n\ + \x05index\x18\x02\x20\x01(\x05R\x05index\"\x90\x01\n\x1aGetEditFieldCont\ + extPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\ + \x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\ + \x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\ + \n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridI\ + d\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_typ\ + e\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\ + \x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\ + \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFiel\ + dOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\ + \n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\ + \n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\ + \x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ + Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ + lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ + \x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05item\ + s\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\x12\ + \x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\x18\ + \x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"_\n\rIndexRowOrder\x12&\n\tro\ + w_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrder\x12\x16\n\x05index\ + \x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_index\"\xbf\x01\n\ + \x11GridRowsChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07block\ + Id\x123\n\rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cins\ + ertedRows\x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bde\ + letedRows\x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bup\ + datedRows\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\ + \n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\ + \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07conte\ + nt\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_i\ + d\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ + \x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\ + \x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\ + \x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04nam\ + e\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ + \x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\ + \x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0\ + R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12InsertFieldPa\ + yload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05fi\ + eld\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ + \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ + \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ + \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ + \x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPayload\ + \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ + id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0\ + R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfie\ + ld_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06\ + frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\ + \x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\ + \x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\ + \x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one\ + _of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\ + \x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0fMoveIt\ + emPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x17\n\ + \x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\x18\x03\ + \x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\x05R\ + \x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\x02ty\ + \"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ + Id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_i\ + d\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0\ + R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\tMoveField\x10\ + \0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\ + \0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0c\ + SingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Check\ + box\x10\x05b\x06proto3\ "; 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 45a1af0518..2d6dbecfe4 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -13,6 +13,7 @@ message Field { bool frozen = 5; bool visibility = 6; int32 width = 7; + bool is_primary = 8; } message FieldOrder { string field_id = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs index 7a1e140140..fb800a9626 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs @@ -47,8 +47,8 @@ mod tests { fn create_default_grid_test() { let grid_id = "1".to_owned(); let build_context = GridBuilder::default() - .add_field(FieldMeta::new("Name", "", FieldType::RichText)) - .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect)) + .add_field(FieldMeta::new("Name", "", FieldType::RichText, true)) + .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect, false)) .add_empty_row() .add_empty_row() .add_empty_row() From f66adb53c9b4e469292f183efdff69efd993ed3b Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 21 Apr 2022 15:59:56 +0800 Subject: [PATCH 176/179] chore: config hover --- .../app_flowy/assets/translations/en.json | 3 +- .../app_flowy/lib/startup/deps_resolver.dart | 3 +- .../grid/cell/checkbox_cell_bloc.dart | 10 +- .../application/grid/cell/date_cell_bloc.dart | 8 +- .../application/grid/cell/text_cell_bloc.dart | 56 ++++++-- .../application/grid/row/row_detail_bloc.dart | 19 +-- .../home/menu/app/header/add_button.dart | 18 ++- .../presentation/home/menu/app/menu_app.dart | 8 +- .../plugins/grid/src/grid_page.dart | 4 +- .../grid/src/widgets/cell/cell_builder.dart | 121 ++++++++++++++++- .../grid/src/widgets/cell/cell_container.dart | 49 ++----- .../grid/src/widgets/cell/checkbox_cell.dart | 5 +- .../grid/src/widgets/cell/date_cell.dart | 13 +- .../grid/src/widgets/cell/number_cell.dart | 15 ++- .../cell/selection_cell/selection_cell.dart | 14 +- .../grid/src/widgets/cell/text_cell.dart | 56 ++++++-- .../grid/src/widgets/header/field_cell.dart | 41 ++++-- .../grid/src/widgets/header/field_editor.dart | 4 +- .../grid/src/widgets/row/row_detail.dart | 119 +++++++++++++++-- .../presentation/widgets/pop_up_action.dart | 42 +++--- .../lib/style_widget/hover.dart | 124 ++++++++++++++++-- 21 files changed, 564 insertions(+), 168 deletions(-) diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 97b0d162ef..a051401446 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -177,7 +177,8 @@ }, "row": { "duplicate": "Duplicate", - "delete": "Delete" + "delete": "Delete", + "textPlaceholder": "Empty" }, "selectOption": { "purpleColor": "Purple", diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 2fd03d639f..8f239f1ece 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -170,7 +170,6 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (cellData, _) => TextCellBloc( - service: CellService(), cellData: cellData, ), ); @@ -189,7 +188,7 @@ void _resolveGridDeps(GetIt getIt) { getIt.registerFactoryParam( (cellData, _) => DateCellBloc( - cellIdentifier: cellData, + cellData: cellData, ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart index 6d2935458a..880267f6c9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart @@ -11,13 +11,13 @@ part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { final CellService _service; - final CellListener _listener; + final CellListener _cellListener; CheckboxCellBloc({ required CellService service, required GridCell cellData, }) : _service = service, - _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), super(CheckboxCellState.initial(cellData)) { on( (event, emit) async { @@ -38,18 +38,18 @@ class CheckboxCellBloc extends Bloc { @override Future close() async { - await _listener.stop(); + await _cellListener.stop(); return super.close(); } void _startListening() { - _listener.updateCellNotifier?.addPublishListener((result) { + _cellListener.updateCellNotifier?.addPublishListener((result) { result.fold( (notificationData) async => await _loadCellData(), (err) => Log.error(err), ); }); - _listener.start(); + _cellListener.start(); } Future _loadCellData() async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart index 532b67ae3a..cbabe6c5fe 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart @@ -15,11 +15,11 @@ class DateCellBloc extends Bloc { final CellListener _cellListener; final SingleFieldListener _fieldListener; - DateCellBloc({required GridCell cellIdentifier}) + DateCellBloc({required GridCell cellData}) : _service = CellService(), - _cellListener = CellListener(rowId: cellIdentifier.rowId, fieldId: cellIdentifier.field.id), - _fieldListener = SingleFieldListener(fieldId: cellIdentifier.field.id), - super(DateCellState.initial(cellIdentifier)) { + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + _fieldListener = SingleFieldListener(fieldId: cellData.field.id), + super(DateCellState.initial(cellData)) { on( (event, emit) async { event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart index ec78136dd3..f32c066c5e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart @@ -1,22 +1,29 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; +import 'cell_listener.dart'; import 'cell_service.dart'; part 'text_cell_bloc.freezed.dart'; class TextCellBloc extends Bloc { - final CellService service; + final CellService _service; + final CellListener _cellListener; TextCellBloc({ - required this.service, required GridCell cellData, - }) : super(TextCellState.initial(cellData)) { + }) : _service = CellService(), + _cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + super(TextCellState.initial(cellData)) { on( (event, emit) async { await event.map( - initial: (_InitialCell value) async {}, + initial: (_InitialCell value) async { + _startListening(); + }, updateText: (_UpdateText value) { updateCellContent(value.text); emit(state.copyWith(content: value.text)); @@ -27,16 +34,28 @@ class TextCellBloc extends Bloc { content: value.cellData.cell?.content ?? "", )); }, + didReceiveCellUpdate: (_DidReceiveCellUpdate value) { + emit(state.copyWith( + cellData: state.cellData.copyWith(cell: value.cell), + content: value.cell.content, + )); + }, ); }, ); } + @override + Future close() async { + await _cellListener.stop(); + return super.close(); + } + void updateCellContent(String content) { final fieldId = state.cellData.field.id; final gridId = state.cellData.gridId; final rowId = state.cellData.rowId; - service.updateCell( + _service.updateCell( data: content, fieldId: fieldId, gridId: gridId, @@ -44,9 +63,29 @@ class TextCellBloc extends Bloc { ); } - @override - Future close() async { - return super.close(); + void _startListening() { + _cellListener.updateCellNotifier?.addPublishListener((result) { + result.fold( + (notificationData) async => await _loadCellData(), + (err) => Log.error(err), + ); + }); + _cellListener.start(); + } + + Future _loadCellData() async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + if (isClosed) { + return; + } + result.fold( + (cell) => add(TextCellEvent.didReceiveCellUpdate(cell)), + (err) => Log.error(err), + ); } } @@ -54,6 +93,7 @@ class TextCellBloc extends Bloc { class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; const factory TextCellEvent.didReceiveCellData(GridCell cellData) = _DidReceiveCellData; + const factory TextCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; const factory TextCellEvent.updateText(String text) = _UpdateText; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart index e93f0be89b..1ba10f7614 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart @@ -22,8 +22,11 @@ class RowDetailBloc extends Bloc { await event.map( initial: (_Initial value) async { await _startListening(); + _loadCellData(); + }, + didReceiveCellDatas: (_DidReceiveCellDatas value) { + emit(state.copyWith(cellDatas: value.cellDatas)); }, - didReceiveCellDatas: (_DidReceiveCellDatas value) {}, ); }, ); @@ -40,16 +43,16 @@ class RowDetailBloc extends Bloc { Future _startListening() async { _rowListenFn = _rowCache.addRowListener( rowId: rowData.rowId, - onUpdated: (cellDatas) => add(RowDetailEvent.didReceiveCellDatas(cellDatas)), + onUpdated: (cellDatas) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())), listenWhen: () => !isClosed, ); } - Future _loadRow(Emitter emit) async { + Future _loadCellData() async { final data = _rowCache.loadCellData(rowData.rowId); - data.foldRight(null, (cellDatas, _) { + data.foldRight(null, (cellDataMap, _) { if (!isClosed) { - add(RowDetailEvent.didReceiveCellDatas(cellDatas)); + add(RowDetailEvent.didReceiveCellDatas(cellDataMap.values.toList())); } }); } @@ -58,16 +61,16 @@ class RowDetailBloc extends Bloc { @freezed class RowDetailEvent with _$RowDetailEvent { const factory RowDetailEvent.initial() = _Initial; - const factory RowDetailEvent.didReceiveCellDatas(CellDataMap cellData) = _DidReceiveCellDatas; + const factory RowDetailEvent.didReceiveCellDatas(List cellDatas) = _DidReceiveCellDatas; } @freezed class RowDetailState with _$RowDetailState { const factory RowDetailState({ - required Option cellDataMap, + required List cellDatas, }) = _RowDetailState; factory RowDetailState.initial() => RowDetailState( - cellDataMap: none(), + cellDatas: List.empty(), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart index 214dc7a198..a7de233006 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/add_button.dart @@ -82,16 +82,14 @@ class CreateItem extends StatelessWidget { return FlowyHover( style: config, - builder: (context, onHover) { - return GestureDetector( - onTap: () => onSelected(pluginBuilder), - child: FlowyText.medium( - pluginBuilder.menuName, - color: theme.textColor, - fontSize: 12, - ).padding(horizontal: 10, vertical: 6), - ); - }, + child: GestureDetector( + onTap: () => onSelected(pluginBuilder), + child: FlowyText.medium( + pluginBuilder.menuName, + color: theme.textColor, + fontSize: 12, + ).padding(horizontal: 10, vertical: 6), + ), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart index 41ba6ab4d1..d028355ed1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart @@ -95,9 +95,11 @@ class _MenuAppState extends State { Widget _renderViewSection(AppDataNotifier notifier) { return MultiProvider( providers: [ChangeNotifierProvider.value(value: notifier)], - child: Consumer(builder: (context, AppDataNotifier notifier, child) { - return ViewSection(appData: notifier); - }), + child: Consumer( + builder: (context, AppDataNotifier notifier, child) { + return ViewSection(appData: notifier); + }, + ), ); } 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 b3d35977b8..0fc69efc42 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row/row_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; @@ -214,8 +213,7 @@ class _GridRowsState extends State<_GridRows> { key: _key, initialItemCount: context.read().state.rows.length, itemBuilder: (BuildContext context, int index, Animation animation) { - final rowData = context.read().state.rows[index]; - return _renderRow(context, rowData, animation); + return _renderRow(context, state.rows[index], animation); }, ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 94f2e0da70..3304de6e51 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -1,13 +1,17 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:flutter/widgets.dart'; +import 'package:provider/provider.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; import 'number_cell.dart'; import 'selection_cell/selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(GridCell cellData) { +GridCellWidget buildGridCell(GridCell cellData, {GridCellStyle? style}) { final key = ValueKey(cellData.field.id + cellData.rowId); switch (cellData.field.fieldType) { case FieldType.Checkbox: @@ -19,7 +23,7 @@ Widget buildGridCell(GridCell cellData) { case FieldType.Number: return NumberCell(cellData: cellData, key: key); case FieldType.RichText: - return GridTextCell(cellData: cellData, key: key); + return GridTextCell(cellData: cellData, key: key, style: style); case FieldType.SingleSelect: return SingleSelectCell(cellData: cellData, key: key); default: @@ -35,3 +39,116 @@ class BlankCell extends StatelessWidget { return Container(); } } + +abstract class GridCellWidget extends HoverWidget { + @override + final ValueNotifier onFocus = ValueNotifier(false); + GridCellWidget({Key? key}) : super(key: key); +} + +abstract class B { + ValueNotifier get onFocus; +} + +abstract class GridCellStyle {} + +// +abstract class HoverWidget extends StatefulWidget { + const HoverWidget({Key? key}) : super(key: key); + + ValueNotifier get onFocus; +} + +class FlowyHover2 extends StatefulWidget { + final HoverWidget child; + const FlowyHover2({required this.child, Key? key}) : super(key: key); + + @override + State createState() => _FlowyHover2State(); +} + +class _FlowyHover2State extends State { + late FlowyHoverState _hoverState; + + @override + void initState() { + _hoverState = FlowyHoverState(); + widget.child.onFocus.addListener(() { + _hoverState.onFocus = widget.child.onFocus.value; + }); + super.initState(); + } + + @override + void dispose() { + _hoverState.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider.value( + value: _hoverState, + child: MouseRegion( + cursor: SystemMouseCursors.click, + opaque: false, + onEnter: (p) => setState(() => _hoverState.onHover = true), + onExit: (p) => setState(() => _hoverState.onHover = false), + child: Stack( + fit: StackFit.expand, + alignment: AlignmentDirectional.center, + children: [ + const _HoverBackground(), + widget.child, + ], + ), + ), + ); + } +} + +class _HoverBackground extends StatelessWidget { + const _HoverBackground({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Consumer( + builder: (context, state, child) { + if (state.onHover || state.onFocus) { + return FlowyHoverContainer( + style: HoverStyle( + borderRadius: Corners.s6Border, + hoverColor: theme.shader6, + ), + ); + } else { + return const SizedBox(); + } + }, + ); + } +} + +class FlowyHoverState extends ChangeNotifier { + bool _onHover = false; + bool _onFocus = false; + + set onHover(bool value) { + if (_onHover != value) { + _onHover = value; + notifyListeners(); + } + } + + bool get onHover => _onHover; + + set onFocus(bool value) { + if (_onFocus != value) { + _onFocus = value; + notifyListeners(); + } + } + + bool get onFocus => _onFocus; +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index 243edae3a9..17c1e87710 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -1,8 +1,8 @@ import 'package:flowy_infra/theme.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; - import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'cell_builder.dart'; class CellStateNotifier extends ChangeNotifier { bool _isFocus = false; @@ -28,7 +28,7 @@ class CellStateNotifier extends ChangeNotifier { } class CellContainer extends StatelessWidget { - final Widget child; + final GridCellWidget child; final Widget? expander; final double width; const CellContainer({ @@ -46,6 +46,9 @@ class CellContainer extends StatelessWidget { selector: (context, notifier) => notifier.isFocus, builder: (context, isFocus, _) { Widget container = Center(child: child); + child.onFocus.addListener(() { + Provider.of(context, listen: false).isFocus = child.onFocus.value; + }); if (expander != null) { container = _CellEnterRegion(child: container, expander: expander!); @@ -75,16 +78,16 @@ class CellContainer extends StatelessWidget { } class _CellEnterRegion extends StatelessWidget { - final Widget expander; final Widget child; - const _CellEnterRegion({required this.expander, required this.child, Key? key}) : super(key: key); + final Widget expander; + const _CellEnterRegion({required this.child, required this.expander, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Selector( selector: (context, notifier) => notifier.onEnter, builder: (context, onEnter, _) { - List children = [child]; + List children = [Expanded(child: child)]; if (onEnter) { children.add(expander); } @@ -93,8 +96,8 @@ class _CellEnterRegion extends StatelessWidget { cursor: SystemMouseCursors.click, onEnter: (p) => Provider.of(context, listen: false).onEnter = true, onExit: (p) => Provider.of(context, listen: false).onEnter = false, - child: Stack( - alignment: AlignmentDirectional.centerEnd, + child: Row( + // alignment: AlignmentDirectional.centerEnd, children: children, ), ); @@ -102,35 +105,3 @@ class _CellEnterRegion extends StatelessWidget { ); } } - -abstract class GridCellWidget extends StatefulWidget { - const GridCellWidget({Key? key}) : super(key: key); - - void setFocus(BuildContext context, bool value) { - Provider.of(context, listen: false).isFocus = value; - } -} - -class CellFocusNode extends FocusNode { - VoidCallback? focusCallback; - - void addCallback(BuildContext context, VoidCallback callback) { - if (focusCallback != null) { - removeListener(focusCallback!); - } - focusCallback = () { - Provider.of(context, listen: false).isFocus = hasFocus; - callback(); - }; - - addListener(focusCallback!); - } - - @override - void dispose() { - if (focusCallback != null) { - removeListener(focusCallback!); - } - super.dispose(); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index cbf8d0fadb..608913d41d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -4,11 +4,12 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'cell_builder.dart'; -class CheckboxCell extends StatefulWidget { +class CheckboxCell extends GridCellWidget { final GridCell cellData; - const CheckboxCell({ + CheckboxCell({ required this.cellData, Key? key, }) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart index dcd2b2f5c2..84d60c797a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart @@ -1,17 +1,22 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:table_calendar/table_calendar.dart'; +import 'cell_builder.dart'; + +abstract class GridCellDelegate { + void onFocus(bool isFocus); + GridCellDelegate get delegate; +} class DateCell extends GridCellWidget { final GridCell cellData; - const DateCell({ + DateCell({ required this.cellData, Key? key, }) : super(key: key); @@ -39,13 +44,13 @@ class _DateCellState extends State { child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { - widget.setFocus(context, true); + widget.onFocus.value = true; _CellCalendar.show( context, onSelected: (day) { context.read().add(DateCellEvent.selectDay(day)); }, - onDismissed: () => widget.setFocus(context, false), + onDismissed: () => widget.onFocus.value = false, ); }, child: MouseRegion( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index 09331e49b5..2d98aa0bd6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -2,14 +2,15 @@ import 'dart:async'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'cell_builder.dart'; + class NumberCell extends GridCellWidget { final GridCell cellData; - const NumberCell({ + NumberCell({ required this.cellData, Key? key, }) : super(key: key); @@ -21,21 +22,23 @@ class NumberCell extends GridCellWidget { class _NumberCellState extends State { late NumberCellBloc _cellBloc; late TextEditingController _controller; - late CellFocusNode _focusNode; + late FocusNode _focusNode; Timer? _delayOperation; @override void initState() { _cellBloc = getIt(param1: widget.cellData)..add(const NumberCellEvent.initial()); _controller = TextEditingController(text: _cellBloc.state.content); - _focusNode = CellFocusNode(); + _focusNode = FocusNode(); + _focusNode.addListener(() { + widget.onFocus.value = _focusNode.hasFocus; + focusChanged(); + }); super.initState(); } @override Widget build(BuildContext context) { - _focusNode.addCallback(context, focusChanged); - return BlocProvider.value( value: _cellBloc, child: BlocConsumer( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 1261a4e5f4..05dd66e224 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -10,7 +10,7 @@ import 'selection_editor.dart'; class SingleSelectCell extends GridCellWidget { final GridCell cellData; - const SingleSelectCell({ + SingleSelectCell({ required this.cellData, Key? key, }) : super(key: key); @@ -38,13 +38,13 @@ class _SingleSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - widget.setFocus(context, true); + widget.onFocus.value = true; SelectOptionCellEditor.show( context, state.cellData, state.options, state.selectedOptions, - () => widget.setFocus(context, false), + () => widget.onFocus.value = false, ); }, child: ClipRRect(child: Row(children: children)), @@ -66,7 +66,7 @@ class _SingleSelectCellState extends State { class MultiSelectCell extends GridCellWidget { final GridCell cellData; - const MultiSelectCell({ + MultiSelectCell({ required this.cellData, Key? key, }) : super(key: key); @@ -94,13 +94,13 @@ class _MultiSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - widget.setFocus(context, true); + widget.onFocus.value = true; SelectOptionCellEditor.show( context, state.cellData, state.options, state.selectedOptions, - () => widget.setFocus(context, false), + () => widget.onFocus.value = false, ); }, child: ClipRRect(child: Row(children: children)), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index 93fb4b15e7..688f8344f7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -1,16 +1,39 @@ import 'dart:async'; -import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'cell_container.dart'; +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'cell_builder.dart'; + +class GridTextCellStyle extends GridCellStyle { + String? placeholder; + Color? hoverColor; + bool filled; + InputBorder? inputBorder; + EdgeInsets? contentPadding; + GridTextCellStyle({ + this.placeholder, + this.hoverColor, + this.filled = false, + this.inputBorder, + this.contentPadding, + }); +} class GridTextCell extends GridCellWidget { final GridCell cellData; - const GridTextCell({ + late final GridTextCellStyle? cellStyle; + GridTextCell({ required this.cellData, + GridCellStyle? style, Key? key, - }) : super(key: key); + }) : super(key: key) { + if (style != null) { + cellStyle = (style as GridTextCellStyle); + } else { + cellStyle = null; + } + } @override State createState() => _GridTextCellState(); @@ -19,21 +42,25 @@ class GridTextCell extends GridCellWidget { class _GridTextCellState extends State { late TextCellBloc _cellBloc; late TextEditingController _controller; - late CellFocusNode _focusNode; + late FocusNode _focusNode; + Timer? _delayOperation; @override void initState() { _cellBloc = getIt(param1: widget.cellData); + _cellBloc.add(const TextCellEvent.initial()); _controller = TextEditingController(text: _cellBloc.state.content); - _focusNode = CellFocusNode(); + _focusNode = FocusNode(); + _focusNode.addListener(() { + widget.onFocus.value = _focusNode.hasFocus; + focusChanged(); + }); super.initState(); } @override Widget build(BuildContext context) { - _focusNode.addCallback(context, focusChanged); - return BlocProvider.value( value: _cellBloc, child: BlocConsumer( @@ -42,6 +69,7 @@ class _GridTextCellState extends State { _controller.text = state.content; } }, + buildWhen: (previous, current) => previous.content != current.content, builder: (context, state) { return TextField( controller: _controller, @@ -50,9 +78,13 @@ class _GridTextCellState extends State { onEditingComplete: () => _focusNode.unfocus(), maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - decoration: const InputDecoration( - contentPadding: EdgeInsets.zero, - border: InputBorder.none, + decoration: InputDecoration( + contentPadding: widget.cellStyle?.contentPadding ?? EdgeInsets.zero, + border: widget.cellStyle?.inputBorder ?? InputBorder.none, + hintText: widget.cellStyle?.placeholder, + hoverColor: widget.cellStyle?.hoverColor ?? Colors.transparent, + filled: widget.cellStyle?.filled ?? false, + fillColor: Colors.transparent, isDense: true, ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index c6009b64af..aa45487fe2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -7,6 +7,7 @@ import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_type_extension.dart'; @@ -20,21 +21,21 @@ class GridFieldCell extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = context.watch(); - return BlocProvider( create: (context) => FieldCellBloc(cellContext: cellContext)..add(const FieldCellEvent.initial()), child: BlocBuilder( builder: (context, state) { - final button = FlowyButton( - hoverColor: theme.shader6, + final button = FieldCellButton( + field: state.field, onTap: () => _showActionSheet(context), - leftIcon: svgWidget(state.field.fieldType.iconName(), color: theme.iconColor), - text: FlowyText.medium(state.field.name, fontSize: 12), - padding: GridSize.cellContentInsets, ); - const line = Positioned(top: 0, bottom: 0, right: 0, child: _DragToExpandLine()); + const line = Positioned( + top: 0, + bottom: 0, + right: 0, + child: _DragToExpandLine(), + ); return _CellContainer( width: state.field.width.toDouble(), @@ -125,9 +126,31 @@ class _DragToExpandLine extends StatelessWidget { borderRadius: BorderRadius.zero, contentMargin: const EdgeInsets.only(left: 5), ), - builder: (_, onHover) => const SizedBox(width: 2), + child: const SizedBox(width: 2), ), ), ); } } + +class FieldCellButton extends StatelessWidget { + final VoidCallback onTap; + final Field field; + const FieldCellButton({ + required this.field, + required this.onTap, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + hoverColor: theme.shader6, + onTap: onTap, + leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), + text: FlowyText.medium(field.name, fontSize: 12), + padding: GridSize.cellContentInsets, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index f503877a4a..6efe439399 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -2,12 +2,14 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/field_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/field/field_switch_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; import 'field_name_input.dart'; import 'field_switcher.dart'; @@ -70,7 +72,7 @@ class _FieldEditorWidget extends StatelessWidget { (field) => ListView( shrinkWrap: true, children: [ - const FlowyText.medium("Edit property", fontSize: 12), + FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12), const VSpace(10), const _FieldNameTextField(), const VSpace(10), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart index e41a4b484b..99e9f108cd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart @@ -1,11 +1,19 @@ import 'package:app_flowy/workspace/application/grid/row/row_detail_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart'; +import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:window_size/window_size.dart'; -class RowDetailPage extends StatelessWidget with FlowyOverlayDelegate { +class RowDetailPage extends StatefulWidget with FlowyOverlayDelegate { final GridRow rowData; final GridRowCache rowCache; @@ -16,24 +24,17 @@ class RowDetailPage extends StatelessWidget with FlowyOverlayDelegate { }) : super(key: key); @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => RowDetailBloc(rowData: rowData, rowCache: rowCache), - child: Container(), - ); - } + State createState() => _RowDetailPageState(); void show(BuildContext context) async { - FlowyOverlay.of(context).remove(identifier()); - - const size = Size(460, 400); final window = await getWindowInfo(); + final size = Size(window.frame.size.width * 0.7, window.frame.size.height * 0.7); FlowyOverlay.of(context).insertWithRect( widget: OverlayContainer( child: this, - constraints: BoxConstraints.tight(const Size(460, 400)), + constraints: BoxConstraints.tight(size), ), - identifier: identifier(), + identifier: RowDetailPage.identifier(), anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), anchorSize: window.frame.size, anchorDirection: AnchorDirection.center, @@ -46,3 +47,97 @@ class RowDetailPage extends StatelessWidget with FlowyOverlayDelegate { return (RowDetailPage).toString(); } } + +class _RowDetailPageState extends State { + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) { + final bloc = RowDetailBloc(rowData: widget.rowData, rowCache: widget.rowCache); + bloc.add(const RowDetailEvent.initial()); + return bloc; + }, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 80, vertical: 40), + child: _PropertyList(), + ), + ); + } +} + +class _PropertyList extends StatelessWidget { + const _PropertyList({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) => previous.cellDatas != current.cellDatas, + builder: (context, state) { + return ListView.separated( + itemCount: state.cellDatas.length, + itemBuilder: (BuildContext context, int index) { + return _RowDetailCell(cellData: state.cellDatas[index]); + }, + separatorBuilder: (BuildContext context, int index) { + return const VSpace(2); + }, + ); + }, + ); + } +} + +class _RowDetailCell extends StatelessWidget { + final GridCell cellData; + const _RowDetailCell({required this.cellData, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final cell = buildGridCell( + cellData, + style: _buildCellStyle(theme, cellData.field.fieldType), + ); + return SizedBox( + height: 36, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 150, + child: FieldCellButton(field: cellData.field, onTap: () {}), + ), + const HSpace(10), + Expanded(child: FlowyHover2(child: cell)), + ], + ), + ); + } +} + +GridCellStyle? _buildCellStyle(AppTheme theme, FieldType fieldType) { + switch (fieldType) { + case FieldType.Checkbox: + return null; + case FieldType.DateTime: + return null; + case FieldType.MultiSelect: + return null; + case FieldType.Number: + return null; + case FieldType.RichText: + return GridTextCellStyle( + hoverColor: theme.shader6, + filled: true, + placeholder: LocaleKeys.grid_row_textPlaceholder.tr(), + contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10), + ); + case FieldType.SingleSelect: + return null; + default: + return null; + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart index cc822a6ef9..cbcec14fee 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart @@ -86,29 +86,27 @@ class ActionCell extends StatelessWidget { return FlowyHover( style: HoverStyle(hoverColor: theme.hover), - builder: (context, onHover) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => onSelected(action), - child: SizedBox( - height: itemHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (action.icon != null) action.icon!, - HSpace(ActionListSizes.itemHPadding), - FlowyText.medium( - action.name, - fontSize: 12, - ), - ], - ), - ).padding( - horizontal: ActionListSizes.padding, - vertical: ActionListSizes.padding, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => onSelected(action), + child: SizedBox( + height: itemHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (action.icon != null) action.icon!, + HSpace(ActionListSizes.itemHPadding), + FlowyText.medium( + action.name, + fontSize: 12, + ), + ], ), - ); - }, + ).padding( + horizontal: ActionListSizes.padding, + vertical: ActionListSizes.padding, + ), + ), ); } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index f8caf35b84..e7c7b183cf 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -1,17 +1,22 @@ import 'package:flutter/material.dart'; // ignore: unused_import import 'package:flowy_infra/time/duration.dart'; +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:provider/provider.dart'; typedef HoverBuilder = Widget Function(BuildContext context, bool onHover); class FlowyHover extends StatefulWidget { final HoverStyle style; - final HoverBuilder builder; + final HoverBuilder? builder; + final Widget? child; final bool Function()? setSelected; const FlowyHover({ Key? key, - required this.builder, + this.builder, + this.child, required this.style, this.setSelected, }) : super(key: key); @@ -27,25 +32,27 @@ class _FlowyHoverState extends State { Widget build(BuildContext context) { return MouseRegion( cursor: SystemMouseCursors.click, + opaque: false, onEnter: (p) => setState(() => _onHover = true), onExit: (p) => setState(() => _onHover = false), - child: render(), + child: renderWidget(), ); } - Widget render() { + Widget renderWidget() { var showHover = _onHover; if (!showHover && widget.setSelected != null) { showHover = widget.setSelected!(); } + final child = widget.child ?? widget.builder!(context, _onHover); if (showHover) { return FlowyHoverContainer( style: widget.style, - child: widget.builder(context, _onHover), + child: child, ); } else { - return widget.builder(context, _onHover); + return child; } } } @@ -67,11 +74,11 @@ class HoverStyle { class FlowyHoverContainer extends StatelessWidget { final HoverStyle style; - final Widget child; + final Widget? child; const FlowyHoverContainer({ Key? key, - required this.child, + this.child, required this.style, }) : super(key: key); @@ -93,3 +100,104 @@ class FlowyHoverContainer extends StatelessWidget { ); } } + +// +abstract class HoverWidget extends StatefulWidget { + const HoverWidget({Key? key}) : super(key: key); + + ValueNotifier get onFocus; +} + +class FlowyHover2 extends StatefulWidget { + final HoverWidget child; + const FlowyHover2({required this.child, Key? key}) : super(key: key); + + @override + State createState() => _FlowyHover2State(); +} + +class _FlowyHover2State extends State { + late FlowyHoverState _hoverState; + + @override + void initState() { + _hoverState = FlowyHoverState(); + widget.child.onFocus.addListener(() { + _hoverState.onFocus = widget.child.onFocus.value; + }); + super.initState(); + } + + @override + void dispose() { + _hoverState.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider.value( + value: _hoverState, + child: MouseRegion( + cursor: SystemMouseCursors.click, + opaque: false, + onEnter: (p) => setState(() => _hoverState.onHover = true), + onExit: (p) => setState(() => _hoverState.onHover = false), + child: Stack( + fit: StackFit.expand, + alignment: AlignmentDirectional.center, + children: [ + const _HoverBackground(), + widget.child, + ], + ), + ), + ); + } +} + +class _HoverBackground extends StatelessWidget { + const _HoverBackground({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Consumer( + builder: (context, state, child) { + if (state.onHover || state.onFocus) { + return FlowyHoverContainer( + style: HoverStyle( + borderRadius: Corners.s6Border, + hoverColor: theme.shader6, + ), + ); + } else { + return const SizedBox(); + } + }, + ); + } +} + +class FlowyHoverState extends ChangeNotifier { + bool _onHover = false; + bool _onFocus = false; + + set onHover(bool value) { + if (_onHover != value) { + _onHover = value; + notifyListeners(); + } + } + + bool get onHover => _onHover; + + set onFocus(bool value) { + if (_onFocus != value) { + _onFocus = value; + notifyListeners(); + } + } + + bool get onFocus => _onFocus; +} From e1711980c6387b14ac249a6173242705c05a9125 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 21 Apr 2022 20:32:48 +0800 Subject: [PATCH 177/179] chore: edit field --- .../grid/src/widgets/cell/cell_builder.dart | 108 ------------------ .../grid/src/widgets/cell/text_cell.dart | 16 +-- .../grid/src/widgets/row/row_detail.dart | 24 +++- .../lib/src/flowy_overlay/flowy_overlay.dart | 61 +++++++--- .../lib/style_widget/hover.dart | 14 ++- 5 files changed, 75 insertions(+), 148 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 3304de6e51..015fea1c32 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -1,10 +1,7 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:flutter/widgets.dart'; -import 'package:provider/provider.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; import 'number_cell.dart'; @@ -46,109 +43,4 @@ abstract class GridCellWidget extends HoverWidget { GridCellWidget({Key? key}) : super(key: key); } -abstract class B { - ValueNotifier get onFocus; -} - abstract class GridCellStyle {} - -// -abstract class HoverWidget extends StatefulWidget { - const HoverWidget({Key? key}) : super(key: key); - - ValueNotifier get onFocus; -} - -class FlowyHover2 extends StatefulWidget { - final HoverWidget child; - const FlowyHover2({required this.child, Key? key}) : super(key: key); - - @override - State createState() => _FlowyHover2State(); -} - -class _FlowyHover2State extends State { - late FlowyHoverState _hoverState; - - @override - void initState() { - _hoverState = FlowyHoverState(); - widget.child.onFocus.addListener(() { - _hoverState.onFocus = widget.child.onFocus.value; - }); - super.initState(); - } - - @override - void dispose() { - _hoverState.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider.value( - value: _hoverState, - child: MouseRegion( - cursor: SystemMouseCursors.click, - opaque: false, - onEnter: (p) => setState(() => _hoverState.onHover = true), - onExit: (p) => setState(() => _hoverState.onHover = false), - child: Stack( - fit: StackFit.expand, - alignment: AlignmentDirectional.center, - children: [ - const _HoverBackground(), - widget.child, - ], - ), - ), - ); - } -} - -class _HoverBackground extends StatelessWidget { - const _HoverBackground({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return Consumer( - builder: (context, state, child) { - if (state.onHover || state.onFocus) { - return FlowyHoverContainer( - style: HoverStyle( - borderRadius: Corners.s6Border, - hoverColor: theme.shader6, - ), - ); - } else { - return const SizedBox(); - } - }, - ); - } -} - -class FlowyHoverState extends ChangeNotifier { - bool _onHover = false; - bool _onFocus = false; - - set onHover(bool value) { - if (_onHover != value) { - _onHover = value; - notifyListeners(); - } - } - - bool get onHover => _onHover; - - set onFocus(bool value) { - if (_onFocus != value) { - _onFocus = value; - notifyListeners(); - } - } - - bool get onFocus => _onFocus; -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index 688f8344f7..4c9c07697e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -7,16 +7,9 @@ import 'cell_builder.dart'; class GridTextCellStyle extends GridCellStyle { String? placeholder; - Color? hoverColor; - bool filled; - InputBorder? inputBorder; - EdgeInsets? contentPadding; + GridTextCellStyle({ this.placeholder, - this.hoverColor, - this.filled = false, - this.inputBorder, - this.contentPadding, }); } @@ -79,12 +72,9 @@ class _GridTextCellState extends State { maxLines: 1, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), decoration: InputDecoration( - contentPadding: widget.cellStyle?.contentPadding ?? EdgeInsets.zero, - border: widget.cellStyle?.inputBorder ?? InputBorder.none, + contentPadding: EdgeInsets.zero, + border: InputBorder.none, hintText: widget.cellStyle?.placeholder, - hoverColor: widget.cellStyle?.hoverColor ?? Colors.transparent, - filled: widget.cellStyle?.filled ?? false, - fillColor: Colors.transparent, isDense: true, ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart index 99e9f108cd..4ba31f783b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart @@ -1,7 +1,9 @@ +import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/row/row_detail_bloc.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; @@ -108,14 +110,29 @@ class _RowDetailCell extends StatelessWidget { children: [ SizedBox( width: 150, - child: FieldCellButton(field: cellData.field, onTap: () {}), + child: FieldCellButton(field: cellData.field, onTap: () => _showFieldEditor(context)), ), const HSpace(10), - Expanded(child: FlowyHover2(child: cell)), + Expanded( + child: FlowyHover2( + child: cell, + contentPadding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), + ), + ), ], ), ); } + + void _showFieldEditor(BuildContext context) { + FieldEditor( + gridId: cellData.gridId, + fieldContextLoader: FieldContextLoaderAdaptor( + gridId: cellData.gridId, + field: cellData.field, + ), + ).show(context); + } } GridCellStyle? _buildCellStyle(AppTheme theme, FieldType fieldType) { @@ -130,10 +147,7 @@ GridCellStyle? _buildCellStyle(AppTheme theme, FieldType fieldType) { return null; case FieldType.RichText: return GridTextCellStyle( - hoverColor: theme.shader6, - filled: true, placeholder: LocaleKeys.grid_row_textPlaceholder.tr(), - contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10), ); case FieldType.SingleSelect: return null; diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 5768c52e60..bddbbd90b8 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -207,8 +207,14 @@ class FlowyOverlayState extends State { final reveredList = _overlayList.reversed.toList(); final firstItem = reveredList.removeAt(0); - firstItem.delegate?.didRemove(); _overlayList.remove(firstItem); + if (firstItem.delegate != null) { + firstItem.delegate!.didRemove(); + + if (firstItem.delegate!.asBarrier()) { + return; + } + } for (final element in reveredList) { if (element.delegate?.asBarrier() ?? false) { @@ -286,27 +292,23 @@ class FlowyOverlayState extends State { @override Widget build(BuildContext context) { - final overlays = _overlayList.map((item) => item.widget); - List children = [widget.child]; - - Widget? child; - if (overlays.isNotEmpty) { - child = Container( - color: style.barrierColor, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: _handleTapOnBackground, - ), - ); - - if (style.blur) { - child = BackdropFilter( - child: child, - filter: ImageFilter.blur(sigmaX: 4, sigmaY: 4), + final overlays = _overlayList.map((item) { + var widget = item.widget; + if (item.delegate?.asBarrier() ?? false) { + widget = Container( + color: style.barrierColor, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: _handleTapOnBackground, + child: widget, + ), ); } - } + return widget; + }).toList(); + List children = [widget.child]; + Widget? child = _renderBackground(overlays); if (child != null) { children.add(child); } @@ -335,4 +337,25 @@ class FlowyOverlayState extends State { void _handleTapOnBackground() { removeAll(); } + + Widget? _renderBackground(List overlays) { + Widget? child; + if (overlays.isNotEmpty) { + child = Container( + color: style.barrierColor, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: _handleTapOnBackground, + ), + ); + + if (style.blur) { + child = BackdropFilter( + child: child, + filter: ImageFilter.blur(sigmaX: 4, sigmaY: 4), + ); + } + } + return child; + } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index e7c7b183cf..5189908192 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -110,7 +110,12 @@ abstract class HoverWidget extends StatefulWidget { class FlowyHover2 extends StatefulWidget { final HoverWidget child; - const FlowyHover2({required this.child, Key? key}) : super(key: key); + final EdgeInsets contentPadding; + const FlowyHover2({ + required this.child, + this.contentPadding = EdgeInsets.zero, + Key? key, + }) : super(key: key); @override State createState() => _FlowyHover2State(); @@ -144,11 +149,14 @@ class _FlowyHover2State extends State { onEnter: (p) => setState(() => _hoverState.onHover = true), onExit: (p) => setState(() => _hoverState.onHover = false), child: Stack( - fit: StackFit.expand, + fit: StackFit.loose, alignment: AlignmentDirectional.center, children: [ const _HoverBackground(), - widget.child, + Padding( + padding: widget.contentPadding, + child: widget.child, + ), ], ), ), From 27c40c7b342b9e86dc396c2c6b319372953879d7 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 21 Apr 2022 20:37:05 +0800 Subject: [PATCH 178/179] chore: fix warnings --- .../lib/workspace/application/grid/row/row_detail_bloc.dart | 2 -- .../presentation/plugins/grid/src/widgets/row/grid_row.dart | 1 - frontend/rust-lib/flowy-grid/src/services/grid_editor.rs | 4 +--- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart index 1ba10f7614..2390dc40a0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart @@ -1,9 +1,7 @@ -import 'dart:collection'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'row_service.dart'; -import 'package:dartz/dartz.dart'; part 'row_detail_bloc.freezed.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 5c08bab8c8..1201120f37 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -242,7 +242,6 @@ class _RowEnterRegionState extends State<_RowEnterRegion> { child: widget.child, ), ); - ; } @override 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 2834222778..8f30c0a7cd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -2,9 +2,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_manager::GridBlockMetaEditorManager; use crate::services::entities::CellIdentifier; -use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder, SelectOption, -}; +use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; use bytes::Bytes; From b9135d26a9bb7e7210fb53eff8a1ee2786c5c6c7 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 21 Apr 2022 21:24:28 +0800 Subject: [PATCH 179/179] fix: insert row index --- .../workspace/presentation/plugins/grid/src/grid_page.dart | 3 ++- .../lib/src/flowy_overlay/flowy_overlay.dart | 1 - .../rust-lib/flowy-grid/src/services/block_meta_editor.rs | 4 ++++ .../rust-lib/flowy-grid/src/services/block_meta_manager.rs | 7 +++++-- 4 files changed, 11 insertions(+), 4 deletions(-) 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 0fc69efc42..6e01d56b66 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 @@ -213,7 +213,8 @@ class _GridRowsState extends State<_GridRows> { key: _key, initialItemCount: context.read().state.rows.length, itemBuilder: (BuildContext context, int index, Animation animation) { - return _renderRow(context, state.rows[index], animation); + final rowData = context.read().state.rows[index]; + return _renderRow(context, rowData, animation); }, ); }, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index bddbbd90b8..91412df599 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -210,7 +210,6 @@ class FlowyOverlayState extends State { _overlayList.remove(firstItem); if (firstItem.delegate != null) { firstItem.delegate!.didRemove(); - if (firstItem.delegate!.asBarrier()) { return; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 977ccccb3d..b4d8bccbe5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -61,6 +61,10 @@ impl ClientGridBlockMetaEditor { let change = block_pad.add_row_meta(row, start_row_id)?; row_count = block_pad.number_of_rows(); + + if row_index.is_none() { + row_index = Some(row_count - 1); + } Ok(change) }) .await?; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index 58c623adc6..5e0927795b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -92,8 +92,11 @@ impl GridBlockMetaEditorManager { let mut row_count = 0; for row in row_metas { let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; - inserted_row_orders.push(IndexRowOrder::from(&row)); - row_count = editor.create_row(row, None).await?.0; + let mut row_order = IndexRowOrder::from(&row); + let (count, index) = editor.create_row(row, None).await?; + row_count = count; + row_order.index = index; + inserted_row_orders.push(row_order); } changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count));