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()) } }