From 6579940dc8f3d9f385baf51c471a56672ca1a5e1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 09:30:13 +0800 Subject: [PATCH] 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)]