mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: impl view data processor
This commit is contained in:
parent
5c155a07bf
commit
1b80934899
@ -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 {
|
||||||
|
@ -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',
|
||||||
|
2
frontend/rust-lib/Cargo.lock
generated
2
frontend/rust-lib/Cargo.lock
generated
@ -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",
|
||||||
|
@ -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]
|
||||||
|
@ -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,
|
||||||
})
|
})
|
||||||
|
@ -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(¶ms.view_id).await?;
|
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_result(ExportData {
|
||||||
data: delta_json,
|
data: delta_json,
|
||||||
export_type: params.export_type,
|
export_type: params.export_type,
|
||||||
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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"}]"#
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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>>>;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>>,
|
||||||
}
|
}
|
||||||
|
@ -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>>,
|
||||||
|
@ -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" }
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)]
|
||||||
|
@ -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))?;
|
||||||
|
@ -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\
|
||||||
|
@ -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;
|
||||||
|
@ -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>) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user