chore: impl view data processor

This commit is contained in:
appflowy 2022-03-05 22:30:42 +08:00
parent 5c155a07bf
commit 1b80934899
32 changed files with 257 additions and 145 deletions

View File

@ -230,21 +230,21 @@ class ResetBlockParams extends $pb.GeneratedMessage {
class BlockDelta 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) 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(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 ..hasRequiredFields = false
; ;
BlockDelta._() : super(); BlockDelta._() : super();
factory BlockDelta({ factory BlockDelta({
$core.String? blockId, $core.String? blockId,
$core.String? deltaJson, $core.String? deltaStr,
}) { }) {
final _result = create(); final _result = create();
if (blockId != null) { if (blockId != null) {
_result.blockId = blockId; _result.blockId = blockId;
} }
if (deltaJson != null) { if (deltaStr != null) {
_result.deltaJson = deltaJson; _result.deltaStr = deltaStr;
} }
return _result; return _result;
} }
@ -279,13 +279,13 @@ class BlockDelta extends $pb.GeneratedMessage {
void clearBlockId() => clearField(1); void clearBlockId() => clearField(1);
@$pb.TagNumber(2) @$pb.TagNumber(2)
$core.String get deltaJson => $_getSZ(1); $core.String get deltaStr => $_getSZ(1);
@$pb.TagNumber(2) @$pb.TagNumber(2)
set deltaJson($core.String v) { $_setString(1, v); } set deltaStr($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2) @$pb.TagNumber(2)
$core.bool hasDeltaJson() => $_has(1); $core.bool hasDeltaStr() => $_has(1);
@$pb.TagNumber(2) @$pb.TagNumber(2)
void clearDeltaJson() => clearField(2); void clearDeltaStr() => clearField(2);
} }
class NewDocUser extends $pb.GeneratedMessage { class NewDocUser extends $pb.GeneratedMessage {

View File

@ -48,12 +48,12 @@ const BlockDelta$json = const {
'1': 'BlockDelta', '1': 'BlockDelta',
'2': const [ '2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, 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`. /// 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') @$core.Deprecated('Use newDocUserDescriptor instead')
const NewDocUser$json = const { const NewDocUser$json = const {
'1': 'NewDocUser', '1': 'NewDocUser',

View File

@ -986,6 +986,7 @@ dependencies = [
name = "flowy-folder" name = "flowy-folder"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait",
"bincode", "bincode",
"bytes", "bytes",
"chrono", "chrono",
@ -1133,6 +1134,7 @@ dependencies = [
name = "flowy-sdk" name = "flowy-sdk"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait",
"bincode", "bincode",
"bytes", "bytes",
"claim 0.5.0", "claim 0.5.0",

View File

@ -7,8 +7,8 @@ edition = "2018"
[lib] [lib]
name = "dart_ffi" name = "dart_ffi"
# this value will change depending on the target os # this value will change depending on the target os
# default cdylib # default staticlib
crate-type = ["cdylib"] crate-type = ["staticlib"]
[dependencies] [dependencies]

View File

@ -140,9 +140,9 @@ impl ClientBlockEditor {
Ok(()) Ok(())
} }
pub async fn block_json(&self) -> FlowyResult<String> { pub async fn delta_str(&self) -> FlowyResult<String> {
let (ret, rx) = oneshot::channel::<CollaborateResult<String>>(); let (ret, rx) = oneshot::channel::<CollaborateResult<String>>();
let msg = EditorCommand::ReadBlockJson { ret }; let msg = EditorCommand::ReadDeltaStr { ret };
let _ = self.edit_cmd_tx.send(msg).await; let _ = self.edit_cmd_tx.send(msg).await;
let json = rx.await.map_err(internal_error)??; let json = rx.await.map_err(internal_error)??;
Ok(json) Ok(json)
@ -196,7 +196,7 @@ fn spawn_edit_queue(
impl ClientBlockEditor { impl ClientBlockEditor {
pub async fn doc_json(&self) -> FlowyResult<String> { pub async fn doc_json(&self) -> FlowyResult<String> {
let (ret, rx) = oneshot::channel::<CollaborateResult<String>>(); let (ret, rx) = oneshot::channel::<CollaborateResult<String>>();
let msg = EditorCommand::ReadBlockJson { ret }; let msg = EditorCommand::ReadDeltaStr { ret };
let _ = self.edit_cmd_tx.send(msg).await; let _ = self.edit_cmd_tx.send(msg).await;
let s = rx.await.map_err(internal_error)??; let s = rx.await.map_err(internal_error)??;
Ok(s) Ok(s)
@ -226,7 +226,7 @@ impl RevisionObjectBuilder for BlockInfoBuilder {
Result::<BlockInfo, FlowyError>::Ok(BlockInfo { Result::<BlockInfo, FlowyError>::Ok(BlockInfo {
block_id: object_id.to_owned(), block_id: object_id.to_owned(),
text: delta.to_delta_json(), text: delta.to_delta_str(),
rev_id, rev_id,
base_rev_id, base_rev_id,
}) })

View File

@ -21,7 +21,7 @@ pub(crate) async fn export_handler(
) -> DataResult<ExportData, FlowyError> { ) -> DataResult<ExportData, FlowyError> {
let params: ExportParams = data.into_inner().try_into()?; let params: ExportParams = data.into_inner().try_into()?;
let editor = manager.open_block(&params.view_id).await?; let editor = manager.open_block(&params.view_id).await?;
let delta_json = editor.block_json().await?; let delta_json = editor.delta_str().await?;
data_result(ExportData { data_result(ExportData {
data: delta_json, data: delta_json,
export_type: params.export_type, export_type: params.export_type,

View File

@ -63,7 +63,7 @@ impl BlockManager {
} }
#[tracing::instrument(level = "debug", skip(self, doc_id), fields(doc_id), err)] #[tracing::instrument(level = "debug", skip(self, doc_id), fields(doc_id), err)]
pub fn delete<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> { pub fn delete_block<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> {
let doc_id = doc_id.as_ref(); let doc_id = doc_id.as_ref();
tracing::Span::current().record("doc_id", &doc_id); tracing::Span::current().record("doc_id", &doc_id);
self.block_editors.remove(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)] #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)]
pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result<BlockDelta, FlowyError> { pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result<BlockDelta, FlowyError> {
let editor = self.get_block_editor(&delta.block_id).await?; let editor = self.get_block_editor(&delta.block_id).await?;
let _ = editor.compose_local_delta(Bytes::from(delta.delta_json)).await?; let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?;
let document_json = editor.block_json().await?; let document_json = editor.delta_str().await?;
Ok(BlockDelta { Ok(BlockDelta {
block_id: delta.block_id.clone(), block_id: delta.block_id.clone(),
delta_json: document_json, delta_str: document_json,
}) })
} }

View File

@ -161,8 +161,8 @@ impl EditBlockQueue {
let _ = self.save_local_delta(delta, md5).await?; let _ = self.save_local_delta(delta, md5).await?;
let _ = ret.send(Ok(())); let _ = ret.send(Ok(()));
} }
EditorCommand::ReadBlockJson { ret } => { EditorCommand::ReadDeltaStr { ret } => {
let data = self.document.read().await.to_json(); let data = self.document.read().await.delta_str();
let _ = ret.send(Ok(data)); let _ = ret.send(Ok(data));
} }
EditorCommand::ReadBlockDelta { ret } => { EditorCommand::ReadBlockDelta { ret } => {
@ -265,7 +265,7 @@ pub(crate) enum EditorCommand {
Redo { Redo {
ret: Ret<()>, ret: Ret<()>,
}, },
ReadBlockJson { ReadDeltaStr {
ret: Ret<String>, ret: Ret<String>,
}, },
#[allow(dead_code)] #[allow(dead_code)]
@ -289,7 +289,7 @@ impl std::fmt::Debug for EditorCommand {
EditorCommand::CanRedo { .. } => "CanRedo", EditorCommand::CanRedo { .. } => "CanRedo",
EditorCommand::Undo { .. } => "Undo", EditorCommand::Undo { .. } => "Undo",
EditorCommand::Redo { .. } => "Redo", EditorCommand::Redo { .. } => "Redo",
EditorCommand::ReadBlockJson { .. } => "ReadDocumentAsJson", EditorCommand::ReadDeltaStr { .. } => "ReadDeltaStr",
EditorCommand::ReadBlockDelta { .. } => "ReadDocumentAsDelta", EditorCommand::ReadBlockDelta { .. } => "ReadDocumentAsDelta",
}; };
f.write_str(s) f.write_str(s)

View File

@ -77,7 +77,7 @@ impl EditorTest {
let delta = self.editor.doc_delta().await.unwrap(); let delta = self.editor.doc_delta().await.unwrap();
if expected_delta != delta { if expected_delta != delta {
eprintln!("✅ expect: {}", expected,); eprintln!("✅ expect: {}", expected,);
eprintln!("❌ receive: {}", delta.to_delta_json()); eprintln!("❌ receive: {}", delta.to_delta_str());
} }
assert_eq!(expected_delta, delta); assert_eq!(expected_delta, delta);
} }

View File

@ -774,7 +774,7 @@ fn delta_compose() {
delta = delta.compose(&d).unwrap(); delta = delta.compose(&d).unwrap();
} }
assert_eq!( assert_eq!(
delta.to_delta_json(), delta.to_delta_str(),
r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\n"}]"# r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\n"}]"#
); );

View File

@ -108,20 +108,20 @@ impl TestBuilder {
TestOp::Insert(delta_i, s, index) => { TestOp::Insert(delta_i, s, index) => {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let delta = document.insert(*index, s).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::Delete(delta_i, iv) => { TestOp::Delete(delta_i, iv) => {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let delta = document.replace(*iv, "").unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::Replace(delta_i, iv, s) => { TestOp::Replace(delta_i, iv, s) => {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let delta = document.replace(*iv, s).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::InsertBold(delta_i, s, iv) => { TestOp::InsertBold(delta_i, s, iv) => {
@ -133,7 +133,7 @@ impl TestBuilder {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let attribute = RichTextAttribute::Bold(*enable); let attribute = RichTextAttribute::Bold(*enable);
let delta = document.format(*iv, attribute).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::Italic(delta_i, iv, enable) => { TestOp::Italic(delta_i, iv, enable) => {
@ -143,28 +143,28 @@ impl TestBuilder {
false => RichTextAttribute::Italic(false), false => RichTextAttribute::Italic(false),
}; };
let delta = document.format(*iv, attribute).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::Header(delta_i, iv, level) => { TestOp::Header(delta_i, iv, level) => {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let attribute = RichTextAttribute::Header(*level); let attribute = RichTextAttribute::Header(*level);
let delta = document.format(*iv, attribute).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::Link(delta_i, iv, link) => { TestOp::Link(delta_i, iv, link) => {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let attribute = RichTextAttribute::Link(link.to_owned()); let attribute = RichTextAttribute::Link(link.to_owned());
let delta = document.format(*iv, attribute).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
TestOp::Bullet(delta_i, iv, enable) => { TestOp::Bullet(delta_i, iv, enable) => {
let document = &mut self.documents[*delta_i]; let document = &mut self.documents[*delta_i];
let attribute = RichTextAttribute::Bullet(*enable); let attribute = RichTextAttribute::Bullet(*enable);
let delta = document.format(*iv, attribute).unwrap(); 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)); self.deltas.insert(*delta_i, Some(delta));
} }
@ -194,15 +194,15 @@ impl TestBuilder {
let delta_a = &self.documents[*delta_a_i].delta(); let delta_a = &self.documents[*delta_a_i].delta();
let delta_b = &self.documents[*delta_b_i].delta(); let delta_b = &self.documents[*delta_b_i].delta();
tracing::debug!("Invert: "); tracing::debug!("Invert: ");
tracing::debug!("a: {}", delta_a.to_delta_json()); tracing::debug!("a: {}", delta_a.to_delta_str());
tracing::debug!("b: {}", delta_b.to_delta_json()); tracing::debug!("b: {}", delta_b.to_delta_str());
let (_, b_prime) = delta_a.transform(delta_b).unwrap(); let (_, b_prime) = delta_a.transform(delta_b).unwrap();
let undo = b_prime.invert(delta_a); let undo = b_prime.invert(delta_a);
let new_delta = delta_a.compose(&b_prime).unwrap(); let new_delta = delta_a.compose(&b_prime).unwrap();
tracing::debug!("new delta: {}", new_delta.to_delta_json()); tracing::debug!("new delta: {}", new_delta.to_delta_str());
tracing::debug!("undo delta: {}", undo.to_delta_json()); tracing::debug!("undo delta: {}", undo.to_delta_str());
let new_delta_after_undo = new_delta.compose(&undo).unwrap(); let new_delta_after_undo = new_delta.compose(&undo).unwrap();
@ -226,7 +226,7 @@ impl TestBuilder {
} }
TestOp::AssertDocJson(delta_i, expected) => { 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 expected_delta: RichTextDelta = serde_json::from_str(expected).unwrap();
let target_delta: RichTextDelta = serde_json::from_str(&delta_json).unwrap(); let target_delta: RichTextDelta = serde_json::from_str(&delta_json).unwrap();
@ -238,7 +238,7 @@ impl TestBuilder {
} }
TestOp::AssertPrimeJson(doc_i, expected) => { 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 expected_prime: RichTextDelta = serde_json::from_str(expected).unwrap();
let target_prime: RichTextDelta = serde_json::from_str(&prime_json).unwrap(); let target_prime: RichTextDelta = serde_json::from_str(&prime_json).unwrap();

View File

@ -92,7 +92,7 @@ fn delta_deserialize_null_test() {
attribute.value = RichTextAttributeValue(None); attribute.value = RichTextAttributeValue(None);
let delta2 = DeltaBuilder::new().retain_with_attributes(7, attribute.into()).build(); 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); assert_eq!(delta1, delta2);
} }
@ -108,10 +108,10 @@ fn document_insert_serde_test() {
let mut document = ClientDocument::new::<PlainDoc>(); let mut document = ClientDocument::new::<PlainDoc>();
document.insert(0, "\n").unwrap(); document.insert(0, "\n").unwrap();
document.insert(0, "123").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"}]"#, json);
assert_eq!( assert_eq!(
r#"[{"insert":"123\n"}]"#, r#"[{"insert":"123\n"}]"#,
ClientDocument::from_json(&json).unwrap().to_json() ClientDocument::from_json(&json).unwrap().delta_str()
); );
} }

View File

@ -42,6 +42,7 @@ bytes = { version = "1.0" }
crossbeam = "0.8" crossbeam = "0.8"
crossbeam-utils = "0.8" crossbeam-utils = "0.8"
chrono = "0.4" chrono = "0.4"
async-trait = "0.1.52"
[dev-dependencies] [dev-dependencies]
serial_test = "0.5.1" serial_test = "0.5.1"

View File

@ -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::{ use crate::{
dart_notification::{send_dart_notification, FolderNotification}, dart_notification::{send_dart_notification, FolderNotification},
entities::workspace::RepeatedWorkspace, entities::workspace::RepeatedWorkspace,
@ -22,11 +8,22 @@ use crate::{
TrashController, ViewController, WorkspaceController, 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! { lazy_static! {
static ref INIT_FOLDER_FLAG: TokioRwLock<HashMap<String, bool>> = TokioRwLock::new(HashMap::new()); static ref INIT_FOLDER_FLAG: TokioRwLock<HashMap<String, bool>> = TokioRwLock::new(HashMap::new());
} }
const FOLDER_ID: &str = "folder"; const FOLDER_ID: &str = "folder";
const FOLDER_ID_SPLIT: &str = ":"; const FOLDER_ID_SPLIT: &str = ":";
#[derive(Clone)] #[derive(Clone)]
@ -72,6 +69,7 @@ impl FolderManager {
user: Arc<dyn WorkspaceUser>, user: Arc<dyn WorkspaceUser>,
cloud_service: Arc<dyn FolderCouldServiceV1>, cloud_service: Arc<dyn FolderCouldServiceV1>,
database: Arc<dyn WorkspaceDatabase>, database: Arc<dyn WorkspaceDatabase>,
data_processors: DataProcessorMap,
block_manager: Arc<BlockManager>, block_manager: Arc<BlockManager>,
web_socket: Arc<dyn RevisionWebSocket>, web_socket: Arc<dyn RevisionWebSocket>,
) -> Self { ) -> Self {
@ -95,6 +93,7 @@ impl FolderManager {
persistence.clone(), persistence.clone(),
cloud_service.clone(), cloud_service.clone(),
trash_controller.clone(), trash_controller.clone(),
data_processors,
block_manager, block_manager,
)); ));
@ -197,7 +196,7 @@ impl DefaultFolderBuilder {
for app in workspace.apps.iter() { for app in workspace.apps.iter() {
for (index, view) in app.belongings.iter().enumerate() { for (index, view) in app.belongings.iter().enumerate() {
let view_data = if index == 0 { let view_data = if index == 0 {
initial_read_me().to_delta_json() initial_read_me().to_delta_str()
} else { } else {
initial_quill_delta_string() initial_quill_delta_string()
}; };
@ -222,3 +221,14 @@ impl FolderManager {
self.folder_editor.read().await.clone().unwrap() 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<String>;
fn data_type(&self) -> ViewDataType;
}
pub type DataProcessorMap = Arc<HashMap<ViewDataType, Arc<dyn ViewDataProcessor + Send + Sync>>>;

View File

@ -6,8 +6,10 @@ use flowy_collaboration::entities::{
use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::client_document::default::initial_quill_delta_string;
use futures::{FutureExt, StreamExt}; use futures::{FutureExt, StreamExt};
use std::collections::HashMap;
use std::{collections::HashSet, sync::Arc}; use std::{collections::HashSet, sync::Arc};
use crate::manager::DataProcessorMap;
use crate::{ use crate::{
dart_notification::{send_dart_notification, FolderNotification}, dart_notification::{send_dart_notification, FolderNotification},
entities::{ entities::{
@ -23,6 +25,7 @@ use crate::{
}; };
use flowy_block::BlockManager; use flowy_block::BlockManager;
use flowy_database::kv::KV; use flowy_database::kv::KV;
use flowy_folder_data_model::entities::view::ViewDataType;
use lib_infra::uuid; use lib_infra::uuid;
const LATEST_VIEW_ID: &str = "latest_view_id"; const LATEST_VIEW_ID: &str = "latest_view_id";
@ -32,6 +35,7 @@ pub(crate) struct ViewController {
cloud_service: Arc<dyn FolderCouldServiceV1>, cloud_service: Arc<dyn FolderCouldServiceV1>,
persistence: Arc<FolderPersistence>, persistence: Arc<FolderPersistence>,
trash_controller: Arc<TrashController>, trash_controller: Arc<TrashController>,
data_processors: DataProcessorMap,
block_manager: Arc<BlockManager>, block_manager: Arc<BlockManager>,
} }
@ -40,15 +44,17 @@ impl ViewController {
user: Arc<dyn WorkspaceUser>, user: Arc<dyn WorkspaceUser>,
persistence: Arc<FolderPersistence>, persistence: Arc<FolderPersistence>,
cloud_service: Arc<dyn FolderCouldServiceV1>, cloud_service: Arc<dyn FolderCouldServiceV1>,
trash_can: Arc<TrashController>, trash_controller: Arc<TrashController>,
document_manager: Arc<BlockManager>, data_processors: DataProcessorMap,
block_manager: Arc<BlockManager>,
) -> Self { ) -> Self {
Self { Self {
user, user,
cloud_service, cloud_service,
persistence, persistence,
trash_controller: trash_can, trash_controller,
block_manager: document_manager, data_processors,
block_manager,
} }
} }
@ -127,11 +133,11 @@ impl ViewController {
#[tracing::instrument(level = "debug", skip(self), err)] #[tracing::instrument(level = "debug", skip(self), err)]
pub(crate) async fn open_view(&self, view_id: &str) -> Result<BlockDelta, FlowyError> { pub(crate) async fn open_view(&self, view_id: &str) -> Result<BlockDelta, FlowyError> {
let editor = self.block_manager.open_block(view_id).await?; 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()); KV::set_str(LATEST_VIEW_ID, view_id.to_owned());
let document_json = editor.block_json().await?;
Ok(BlockDelta { Ok(BlockDelta {
block_id: view_id.to_string(), block_id: view_id.to_string(),
delta_json: document_json, delta_str,
}) })
} }
@ -160,14 +166,14 @@ impl ViewController {
.await?; .await?;
let editor = self.block_manager.open_block(view_id).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 { let duplicate_params = CreateViewParams {
belong_to_id: view.belong_to_id.clone(), belong_to_id: view.belong_to_id.clone(),
name: format!("{} (copy)", &view.name), name: format!("{} (copy)", &view.name),
desc: view.desc, desc: view.desc,
thumbnail: view.thumbnail, thumbnail: view.thumbnail,
data_type: view.data_type, data_type: view.data_type,
data: document_json, data: delta_str,
view_id: uuid(), view_id: uuid(),
ext_data: view.ext_data, ext_data: view.ext_data,
plugin_type: view.plugin_type, plugin_type: view.plugin_type,
@ -208,11 +214,6 @@ impl ViewController {
Ok(view) Ok(view)
} }
pub(crate) async fn receive_delta(&self, params: BlockDelta) -> Result<BlockDelta, FlowyError> {
let doc = self.block_manager.receive_local_delta(params).await?;
Ok(doc)
}
pub(crate) async fn latest_visit_view(&self) -> FlowyResult<Option<View>> { pub(crate) async fn latest_visit_view(&self) -> FlowyResult<Option<View>> {
match KV::get_str(LATEST_VIEW_ID) { match KV::get_str(LATEST_VIEW_ID) {
None => Ok(None), 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( async fn handle_trash_event(
persistence: Arc<FolderPersistence>, persistence: Arc<FolderPersistence>,
document_manager: Arc<BlockManager>, block_manager: Arc<BlockManager>,
trash_can: Arc<TrashController>, trash_can: Arc<TrashController>,
event: TrashEvent, event: TrashEvent,
) { ) {
@ -352,7 +353,7 @@ async fn handle_trash_event(
for identifier in identifiers.items { for identifier in identifiers.items {
let view = transaction.read_view(&identifier.id)?; let view = transaction.read_view(&identifier.id)?;
let _ = transaction.delete_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); notify_ids.insert(view.belong_to_id);
} }

View File

@ -41,29 +41,8 @@ impl GridManager {
} }
#[tracing::instrument(level = "debug", skip_all, err)] #[tracing::instrument(level = "debug", skip_all, err)]
pub async fn create_grid<T: AsRef<str>>( pub async fn create_grid<T: AsRef<str>>(&self, grid_id: T, revisions: RepeatedRevision) -> FlowyResult<()> {
&self,
grid_id: T,
fields: Option<Vec<Field>>,
rows: Option<Vec<RawRow>>,
) -> FlowyResult<()> {
let grid_id = grid_id.as_ref(); 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::<Vec<_>>();
}
if let Some(rows) = rows {
row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::<Vec<_>>();
}
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 db_pool = self.grid_user.db_pool()?;
let rev_manager = self.make_grid_rev_manager(grid_id, db_pool)?; let rev_manager = self.make_grid_rev_manager(grid_id, db_pool)?;
let _ = rev_manager.reset_object(revisions).await?; 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<Vec<Field>>,
rows: Option<Vec<RawRow>>,
) -> 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::<Vec<_>>();
}
if let Some(rows) = rows {
row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::<Vec<_>>();
}
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 { pub struct GridEditors {
inner: DashMap<String, Arc<ClientGridEditor>>, inner: DashMap<String, Arc<ClientGridEditor>>,
} }

View File

@ -155,6 +155,10 @@ impl ClientGridEditor {
self.grid_pad.read().await.grid_data() self.grid_pad.read().await.grid_data()
} }
pub async fn delta_str(&self) -> String {
self.grid_pad.read().await.delta_str()
}
async fn modify<F>(&self, f: F) -> FlowyResult<()> async fn modify<F>(&self, f: F) -> FlowyResult<()>
where where
F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult<Option<GridChange>>, F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult<Option<GridChange>>,

View File

@ -23,7 +23,7 @@ color-eyre = { version = "0.5", default-features = false }
bytes = "1.0" bytes = "1.0"
tokio = { version = "1", features = ["rt"] } tokio = { version = "1", features = ["rt"] }
parking_lot = "0.11" parking_lot = "0.11"
async-trait = "0.1.52"
flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" }
lib-ws = { path = "../../../shared-lib/lib-ws" } lib-ws = { path = "../../../shared-lib/lib-ws" }

View File

@ -1,12 +1,17 @@
use async_trait::async_trait;
use bytes::Bytes; use bytes::Bytes;
use flowy_block::BlockManager; use flowy_block::BlockManager;
use flowy_collaboration::entities::revision::RepeatedRevision;
use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
use flowy_database::ConnectionPool; use flowy_database::ConnectionPool;
use flowy_folder::manager::{DataProcessorMap, ViewDataProcessor};
use flowy_folder::prelude::{FlowyResult, ViewDataType};
use flowy_folder::{ use flowy_folder::{
errors::{internal_error, FlowyError}, errors::{internal_error, FlowyError},
event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser},
manager::FolderManager, manager::FolderManager,
}; };
use flowy_grid::manager::GridManager;
use flowy_net::ClientServerConfiguration; use flowy_net::ClientServerConfiguration;
use flowy_net::{ use flowy_net::{
http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, 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 futures_core::future::BoxFuture;
use lib_infra::future::BoxResultFuture; use lib_infra::future::BoxResultFuture;
use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
use std::collections::HashMap;
use std::{convert::TryInto, sync::Arc}; use std::{convert::TryInto, sync::Arc};
pub struct FolderDepsResolver(); pub struct FolderDepsResolver();
@ -24,8 +30,9 @@ impl FolderDepsResolver {
local_server: Option<Arc<LocalServer>>, local_server: Option<Arc<LocalServer>>,
user_session: Arc<UserSession>, user_session: Arc<UserSession>,
server_config: &ClientServerConfiguration, server_config: &ClientServerConfiguration,
ws_conn: &Arc<FlowyWebSocketConnect>,
block_manager: &Arc<BlockManager>, block_manager: &Arc<BlockManager>,
ws_conn: Arc<FlowyWebSocketConnect>, grid_manager: &Arc<GridManager>,
) -> Arc<FolderManager> { ) -> Arc<FolderManager> {
let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone())); let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone()));
let database: Arc<dyn WorkspaceDatabase> = Arc::new(WorkspaceDatabaseImpl(user_session)); let database: Arc<dyn WorkspaceDatabase> = Arc::new(WorkspaceDatabaseImpl(user_session));
@ -35,8 +42,17 @@ impl FolderDepsResolver {
Some(local_server) => local_server, Some(local_server) => local_server,
}; };
let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone());
let folder_manager = Arc::new( 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()) { 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<BlockManager>, grid_manager: Arc<GridManager>) -> DataProcessorMap {
let mut map: HashMap<ViewDataType, Arc<dyn ViewDataProcessor + Send + Sync>> = 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<UserSession>); struct WorkspaceDatabaseImpl(Arc<UserSession>);
impl WorkspaceDatabase for WorkspaceDatabaseImpl { impl WorkspaceDatabase for WorkspaceDatabaseImpl {
fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError> { fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError> {
@ -110,3 +138,61 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl {
}); });
} }
} }
struct BlockManagerViewDataImpl(Arc<BlockManager>);
#[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<String> {
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<GridManager>);
#[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<String> {
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
}
}

View File

@ -111,17 +111,18 @@ impl FlowySDK {
&config.server_config, &config.server_config,
); );
let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone());
let folder_manager = FolderDepsResolver::resolve( let folder_manager = FolderDepsResolver::resolve(
local_server.clone(), local_server.clone(),
user_session.clone(), user_session.clone(),
&config.server_config, &config.server_config,
&ws_conn,
&block_manager, &block_manager,
ws_conn.clone(), &grid_manager,
) )
.await; .await;
let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone());
if let Some(local_server) = local_server.as_ref() { if let Some(local_server) = local_server.as_ref() {
local_server.run(); local_server.run();
} }

View File

@ -7,7 +7,7 @@ pub fn initial_quill_delta() -> RichTextDelta {
#[inline] #[inline]
pub fn initial_quill_delta_string() -> String { pub fn initial_quill_delta_string() -> String {
initial_quill_delta().to_delta_json() initial_quill_delta().to_delta_str()
} }
#[inline] #[inline]
@ -22,6 +22,6 @@ mod tests {
#[test] #[test]
fn load_read_me() { fn load_read_me() {
println!("{}", initial_read_me().to_delta_json()); println!("{}", initial_read_me().to_delta_str());
} }
} }

View File

@ -58,8 +58,8 @@ impl ClientDocument {
Ok(Self::from_delta(delta)) Ok(Self::from_delta(delta))
} }
pub fn to_json(&self) -> String { pub fn delta_str(&self) -> String {
self.delta.to_delta_json() self.delta.to_delta_str()
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -84,7 +84,7 @@ impl ClientDocument {
} }
pub fn set_delta(&mut self, data: RichTextDelta) { 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; self.delta = data;
match &self.notify { match &self.notify {
@ -96,7 +96,7 @@ impl ClientDocument {
} }
pub fn compose_delta(&mut self, delta: RichTextDelta) -> Result<(), CollaborateError> { 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 composed_delta = self.delta.compose(&delta)?;
let mut undo_delta = delta.invert(&self.delta); let mut undo_delta = delta.invert(&self.delta);

View File

@ -86,6 +86,10 @@ impl GridPad {
grid_ref.clone() grid_ref.clone()
} }
pub fn delta_str(&self) -> String {
self.delta.to_delta_str()
}
pub fn field_orders(&self) -> &RepeatedFieldOrder { pub fn field_orders(&self) -> &RepeatedFieldOrder {
&self.grid.field_orders &self.grid.field_orders
} }

View File

@ -46,7 +46,7 @@ impl std::convert::TryFrom<Revision> for BlockInfo {
} }
let delta = RichTextDelta::from_bytes(&revision.delta_data)?; let delta = RichTextDelta::from_bytes(&revision.delta_data)?;
let doc_json = delta.to_delta_json(); let doc_json = delta.to_delta_str();
Ok(BlockInfo { Ok(BlockInfo {
block_id: revision.object_id, block_id: revision.object_id,
@ -72,7 +72,7 @@ pub struct BlockDelta {
pub block_id: String, pub block_id: String,
#[pb(index = 2)] #[pb(index = 2)]
pub delta_json: String, pub delta_str: String,
} }
#[derive(ProtoBuf, Default, Debug, Clone)] #[derive(ProtoBuf, Default, Debug, Clone)]

View File

@ -89,7 +89,7 @@ impl std::fmt::Debug for Revision {
let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?; let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?;
match RichTextDelta::from_bytes(&self.delta_data) { match RichTextDelta::from_bytes(&self.delta_data) {
Ok(delta) => { 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) => { Err(e) => {
let _ = f.write_fmt(format_args!("delta {:?}", e))?; let _ = f.write_fmt(format_args!("delta {:?}", e))?;

View File

@ -730,7 +730,7 @@ impl ::protobuf::reflect::ProtobufValue for ResetBlockParams {
pub struct BlockDelta { pub struct BlockDelta {
// message fields // message fields
pub block_id: ::std::string::String, pub block_id: ::std::string::String,
pub delta_json: ::std::string::String, pub delta_str: ::std::string::String,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
@ -773,30 +773,30 @@ impl BlockDelta {
::std::mem::replace(&mut self.block_id, ::std::string::String::new()) ::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 { pub fn get_delta_str(&self) -> &str {
&self.delta_json &self.delta_str
} }
pub fn clear_delta_json(&mut self) { pub fn clear_delta_str(&mut self) {
self.delta_json.clear(); self.delta_str.clear();
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_delta_json(&mut self, v: ::std::string::String) { pub fn set_delta_str(&mut self, v: ::std::string::String) {
self.delta_json = v; self.delta_str = v;
} }
// Mutable pointer to the field. // Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first. // If field is not initialized, it is initialized with default value first.
pub fn mut_delta_json(&mut self) -> &mut ::std::string::String { pub fn mut_delta_str(&mut self) -> &mut ::std::string::String {
&mut self.delta_json &mut self.delta_str
} }
// Take field // Take field
pub fn take_delta_json(&mut self) -> ::std::string::String { pub fn take_delta_str(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.delta_json, ::std::string::String::new()) ::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)?; ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?;
}, },
2 => { 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())?; ::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() { if !self.block_id.is_empty() {
my_size += ::protobuf::rt::string_size(1, &self.block_id); my_size += ::protobuf::rt::string_size(1, &self.block_id);
} }
if !self.delta_json.is_empty() { if !self.delta_str.is_empty() {
my_size += ::protobuf::rt::string_size(2, &self.delta_json); my_size += ::protobuf::rt::string_size(2, &self.delta_str);
} }
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size); self.cached_size.set(my_size);
@ -842,8 +842,8 @@ impl ::protobuf::Message for BlockDelta {
if !self.block_id.is_empty() { if !self.block_id.is_empty() {
os.write_string(1, &self.block_id)?; os.write_string(1, &self.block_id)?;
} }
if !self.delta_json.is_empty() { if !self.delta_str.is_empty() {
os.write_string(2, &self.delta_json)?; os.write_string(2, &self.delta_str)?;
} }
os.write_unknown_fields(self.get_unknown_fields())?; os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(()) ::std::result::Result::Ok(())
@ -889,9 +889,9 @@ impl ::protobuf::Message for BlockDelta {
|m: &mut BlockDelta| { &mut m.block_id }, |m: &mut BlockDelta| { &mut m.block_id },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"delta_json", "delta_str",
|m: &BlockDelta| { &m.delta_json }, |m: &BlockDelta| { &m.delta_str },
|m: &mut BlockDelta| { &mut m.delta_json }, |m: &mut BlockDelta| { &mut m.delta_str },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockDelta>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockDelta>(
"BlockDelta", "BlockDelta",
@ -910,7 +910,7 @@ impl ::protobuf::Message for BlockDelta {
impl ::protobuf::Clear for BlockDelta { impl ::protobuf::Clear for BlockDelta {
fn clear(&mut self) { fn clear(&mut self) {
self.block_id.clear(); self.block_id.clear();
self.delta_json.clear(); self.delta_str.clear();
self.unknown_fields.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\ \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\ \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\ 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\ \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\ \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\ \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\ ocId\"\x1f\n\x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\

View File

@ -17,7 +17,7 @@ message ResetBlockParams {
} }
message BlockDelta { message BlockDelta {
string block_id = 1; string block_id = 1;
string delta_json = 2; string delta_str = 2;
} }
message NewDocUser { message NewDocUser {
string user_id = 1; string user_id = 1;

View File

@ -39,7 +39,7 @@ impl RevisionSyncObject<RichTextAttributes> for ServerDocument {
} }
fn to_json(&self) -> String { fn to_json(&self) -> String {
self.delta.to_delta_json() self.delta.to_delta_str()
} }
fn set_delta(&mut self, new_delta: Delta<RichTextAttributes>) { fn set_delta(&mut self, new_delta: Delta<RichTextAttributes>) {

View File

@ -32,7 +32,7 @@ impl RevisionSyncObject<PlainTextAttributes> for ServerFolder {
} }
fn to_json(&self) -> String { fn to_json(&self) -> String {
self.delta.to_delta_json() self.delta.to_delta_str()
} }
fn set_delta(&mut self, new_delta: PlainTextDelta) { fn set_delta(&mut self, new_delta: PlainTextDelta) {

View File

@ -189,7 +189,7 @@ pub fn make_folder_pb_from_revisions_pb(
folder_delta = folder_delta.compose(&delta)?; 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(); let mut folder_info = FolderInfoPB::new();
folder_info.set_folder_id(folder_id.to_owned()); folder_info.set_folder_id(folder_id.to_owned());
folder_info.set_text(text); folder_info.set_text(text);
@ -239,7 +239,7 @@ pub fn make_document_info_pb_from_revisions_pb(
document_delta = document_delta.compose(&delta)?; 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(); let mut block_info = BlockInfoPB::new();
block_info.set_block_id(doc_id.to_owned()); block_info.set_block_id(doc_id.to_owned());
block_info.set_text(text); block_info.set_text(text);

View File

@ -80,7 +80,7 @@ impl std::convert::From<View> 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)] #[repr(u8)]
pub enum ViewDataType { pub enum ViewDataType {
RichText = 0, RichText = 0,

View File

@ -521,7 +521,7 @@ impl<T> Delta<T>
where where
T: Attributes + serde::Serialize, 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()) serde_json::to_string(self).unwrap_or_else(|_| "".to_owned())
} }
@ -530,7 +530,7 @@ where
} }
pub fn to_bytes(&self) -> Bytes { pub fn to_bytes(&self) -> Bytes {
let json = self.to_delta_json(); let json = self.to_delta_str();
Bytes::from(json.into_bytes()) Bytes::from(json.into_bytes())
} }
} }