document_event.rs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. use flowy_document2::entities::*;
  2. use flowy_document2::event_map::DocumentEvent;
  3. use flowy_folder2::entities::{CreateViewPayloadPB, ViewLayoutPB, ViewPB};
  4. use flowy_folder2::event_map::FolderEvent;
  5. use crate::document::utils::{gen_id, gen_text_block_data};
  6. use crate::event_builder::EventBuilder;
  7. use crate::FlowyCoreTest;
  8. const TEXT_BLOCK_TY: &str = "paragraph";
  9. pub struct DocumentEventTest {
  10. inner: FlowyCoreTest,
  11. }
  12. pub struct OpenDocumentData {
  13. pub id: String,
  14. pub data: DocumentDataPB,
  15. }
  16. impl DocumentEventTest {
  17. pub async fn new() -> Self {
  18. let sdk = FlowyCoreTest::new_with_guest_user().await;
  19. Self { inner: sdk }
  20. }
  21. pub fn new_with_core(core: FlowyCoreTest) -> Self {
  22. Self { inner: core }
  23. }
  24. pub async fn create_document(&self) -> ViewPB {
  25. let core = &self.inner;
  26. let current_workspace = core.get_current_workspace().await.workspace;
  27. let parent_id = current_workspace.id.clone();
  28. let payload = CreateViewPayloadPB {
  29. parent_view_id: parent_id.to_string(),
  30. name: "document".to_string(),
  31. desc: "".to_string(),
  32. thumbnail: None,
  33. layout: ViewLayoutPB::Document,
  34. initial_data: vec![],
  35. meta: Default::default(),
  36. set_as_current: true,
  37. index: None,
  38. };
  39. EventBuilder::new(core.clone())
  40. .event(FolderEvent::CreateView)
  41. .payload(payload)
  42. .async_send()
  43. .await
  44. .parse::<ViewPB>()
  45. }
  46. pub async fn open_document(&self, doc_id: String) -> OpenDocumentData {
  47. let core = &self.inner;
  48. let payload = OpenDocumentPayloadPB {
  49. document_id: doc_id.clone(),
  50. };
  51. let data = EventBuilder::new(core.clone())
  52. .event(DocumentEvent::OpenDocument)
  53. .payload(payload)
  54. .async_send()
  55. .await
  56. .parse::<DocumentDataPB>();
  57. OpenDocumentData { id: doc_id, data }
  58. }
  59. pub async fn get_block(&self, doc_id: &str, block_id: &str) -> Option<BlockPB> {
  60. let document = self.open_document(doc_id.to_string()).await;
  61. document.data.blocks.get(block_id).cloned()
  62. }
  63. pub async fn get_page_id(&self, doc_id: &str) -> String {
  64. let data = self.get_document_data(doc_id).await;
  65. data.page_id
  66. }
  67. pub async fn get_document_data(&self, doc_id: &str) -> DocumentDataPB {
  68. let document = self.open_document(doc_id.to_string()).await;
  69. document.data
  70. }
  71. pub async fn get_block_children(&self, doc_id: &str, block_id: &str) -> Option<Vec<String>> {
  72. let block = self.get_block(doc_id, block_id).await;
  73. block.as_ref()?;
  74. let document_data = self.get_document_data(doc_id).await;
  75. let children_map = document_data.meta.children_map;
  76. let children_id = block.unwrap().children_id;
  77. children_map.get(&children_id).map(|c| c.children.clone())
  78. }
  79. pub async fn apply_actions(&self, payload: ApplyActionPayloadPB) {
  80. let core = &self.inner;
  81. EventBuilder::new(core.clone())
  82. .event(DocumentEvent::ApplyAction)
  83. .payload(payload)
  84. .async_send()
  85. .await;
  86. }
  87. pub async fn undo(&self, doc_id: String) -> DocumentRedoUndoResponsePB {
  88. let core = &self.inner;
  89. let payload = DocumentRedoUndoPayloadPB {
  90. document_id: doc_id.clone(),
  91. };
  92. EventBuilder::new(core.clone())
  93. .event(DocumentEvent::Undo)
  94. .payload(payload)
  95. .async_send()
  96. .await
  97. .parse::<DocumentRedoUndoResponsePB>()
  98. }
  99. pub async fn redo(&self, doc_id: String) -> DocumentRedoUndoResponsePB {
  100. let core = &self.inner;
  101. let payload = DocumentRedoUndoPayloadPB {
  102. document_id: doc_id.clone(),
  103. };
  104. EventBuilder::new(core.clone())
  105. .event(DocumentEvent::Redo)
  106. .payload(payload)
  107. .async_send()
  108. .await
  109. .parse::<DocumentRedoUndoResponsePB>()
  110. }
  111. pub async fn can_undo_redo(&self, doc_id: String) -> DocumentRedoUndoResponsePB {
  112. let core = &self.inner;
  113. let payload = DocumentRedoUndoPayloadPB {
  114. document_id: doc_id.clone(),
  115. };
  116. EventBuilder::new(core.clone())
  117. .event(DocumentEvent::CanUndoRedo)
  118. .payload(payload)
  119. .async_send()
  120. .await
  121. .parse::<DocumentRedoUndoResponsePB>()
  122. }
  123. /// Insert a new text block at the index of parent's children.
  124. /// return the new block id.
  125. pub async fn insert_index(
  126. &self,
  127. document_id: &str,
  128. text: &str,
  129. index: usize,
  130. parent_id: Option<&str>,
  131. ) -> String {
  132. let text = text.to_string();
  133. let page_id = self.get_page_id(document_id).await;
  134. let parent_id = parent_id
  135. .map(|id| id.to_string())
  136. .unwrap_or_else(|| page_id);
  137. let parent_children = self.get_block_children(document_id, &parent_id).await;
  138. let prev_id = {
  139. // If index is 0, then the new block will be the first child of parent.
  140. if index == 0 {
  141. None
  142. } else {
  143. parent_children.and_then(|children| {
  144. // If index is greater than the length of children, then the new block will be the last child of parent.
  145. if index >= children.len() {
  146. children.last().cloned()
  147. } else {
  148. children.get(index - 1).cloned()
  149. }
  150. })
  151. }
  152. };
  153. let new_block_id = gen_id();
  154. let data = gen_text_block_data(&text);
  155. let new_block = BlockPB {
  156. id: new_block_id.clone(),
  157. ty: TEXT_BLOCK_TY.to_string(),
  158. data,
  159. parent_id: parent_id.clone(),
  160. children_id: gen_id(),
  161. };
  162. let action = BlockActionPB {
  163. action: BlockActionTypePB::Insert,
  164. payload: BlockActionPayloadPB {
  165. block: new_block,
  166. prev_id,
  167. parent_id: Some(parent_id),
  168. },
  169. };
  170. let payload = ApplyActionPayloadPB {
  171. document_id: document_id.to_string(),
  172. actions: vec![action],
  173. };
  174. self.apply_actions(payload).await;
  175. new_block_id
  176. }
  177. pub async fn update(&self, document_id: &str, block_id: &str, text: &str) {
  178. let block = self.get_block(document_id, block_id).await.unwrap();
  179. let data = gen_text_block_data(text);
  180. let new_block = {
  181. let mut new_block = block.clone();
  182. new_block.data = data;
  183. new_block
  184. };
  185. let action = BlockActionPB {
  186. action: BlockActionTypePB::Update,
  187. payload: BlockActionPayloadPB {
  188. block: new_block,
  189. prev_id: None,
  190. parent_id: Some(block.parent_id.clone()),
  191. },
  192. };
  193. let payload = ApplyActionPayloadPB {
  194. document_id: document_id.to_string(),
  195. actions: vec![action],
  196. };
  197. self.apply_actions(payload).await;
  198. }
  199. pub async fn delete(&self, document_id: &str, block_id: &str) {
  200. let block = self.get_block(document_id, block_id).await.unwrap();
  201. let parent_id = block.parent_id.clone();
  202. let action = BlockActionPB {
  203. action: BlockActionTypePB::Delete,
  204. payload: BlockActionPayloadPB {
  205. block,
  206. prev_id: None,
  207. parent_id: Some(parent_id),
  208. },
  209. };
  210. let payload = ApplyActionPayloadPB {
  211. document_id: document_id.to_string(),
  212. actions: vec![action],
  213. };
  214. self.apply_actions(payload).await;
  215. }
  216. }