event_handler.rs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * The following code defines functions that handle creating, opening, and closing documents,
  3. * as well as performing actions on documents. These functions make use of a DocumentManager,
  4. * which you can think of as a higher-level interface to interact with documents.
  5. */
  6. use std::sync::{Arc, Weak};
  7. use collab_document::blocks::{
  8. json_str_to_hashmap, Block, BlockAction, BlockActionPayload, BlockActionType, BlockEvent,
  9. BlockEventPayload, DeltaType,
  10. };
  11. use flowy_error::{FlowyError, FlowyResult};
  12. use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
  13. use crate::entities::*;
  14. use crate::{manager::DocumentManager, parser::json::parser::JsonToDocumentParser};
  15. fn upgrade_document(
  16. document_manager: AFPluginState<Weak<DocumentManager>>,
  17. ) -> FlowyResult<Arc<DocumentManager>> {
  18. let manager = document_manager
  19. .upgrade()
  20. .ok_or(FlowyError::internal().context("The document manager is already dropped"))?;
  21. Ok(manager)
  22. }
  23. // Handler for creating a new document
  24. pub(crate) async fn create_document_handler(
  25. data: AFPluginData<CreateDocumentPayloadPB>,
  26. manager: AFPluginState<Weak<DocumentManager>>,
  27. ) -> FlowyResult<()> {
  28. let manager = upgrade_document(manager)?;
  29. let params: CreateDocumentParams = data.into_inner().try_into()?;
  30. manager.create_document(&params.document_id, params.initial_data)?;
  31. Ok(())
  32. }
  33. // Handler for opening an existing document
  34. pub(crate) async fn open_document_handler(
  35. data: AFPluginData<OpenDocumentPayloadPB>,
  36. manager: AFPluginState<Weak<DocumentManager>>,
  37. ) -> DataResult<DocumentDataPB, FlowyError> {
  38. let manager = upgrade_document(manager)?;
  39. let params: OpenDocumentParams = data.into_inner().try_into()?;
  40. let doc_id = params.document_id;
  41. let document = manager.get_document(&doc_id).await?;
  42. let document_data = document.lock().get_document_data()?;
  43. data_result_ok(DocumentDataPB::from(document_data))
  44. }
  45. pub(crate) async fn close_document_handler(
  46. data: AFPluginData<CloseDocumentPayloadPB>,
  47. manager: AFPluginState<Weak<DocumentManager>>,
  48. ) -> FlowyResult<()> {
  49. let manager = upgrade_document(manager)?;
  50. let params: CloseDocumentParams = data.into_inner().try_into()?;
  51. let doc_id = params.document_id;
  52. manager.close_document(&doc_id)?;
  53. Ok(())
  54. }
  55. // Get the content of the existing document,
  56. // if the document does not exist, return an error.
  57. pub(crate) async fn get_document_data_handler(
  58. data: AFPluginData<OpenDocumentPayloadPB>,
  59. manager: AFPluginState<Weak<DocumentManager>>,
  60. ) -> DataResult<DocumentDataPB, FlowyError> {
  61. let manager = upgrade_document(manager)?;
  62. let params: OpenDocumentParams = data.into_inner().try_into()?;
  63. let doc_id = params.document_id;
  64. let document_data = manager.get_document_data(&doc_id).await?;
  65. data_result_ok(DocumentDataPB::from(document_data))
  66. }
  67. // Handler for applying an action to a document
  68. pub(crate) async fn apply_action_handler(
  69. data: AFPluginData<ApplyActionPayloadPB>,
  70. manager: AFPluginState<Weak<DocumentManager>>,
  71. ) -> FlowyResult<()> {
  72. let manager = upgrade_document(manager)?;
  73. let params: ApplyActionParams = data.into_inner().try_into()?;
  74. let doc_id = params.document_id;
  75. let document = manager.get_document(&doc_id).await?;
  76. let actions = params.actions;
  77. document.lock().apply_action(actions);
  78. Ok(())
  79. }
  80. pub(crate) async fn convert_data_to_document(
  81. data: AFPluginData<ConvertDataPayloadPB>,
  82. ) -> DataResult<DocumentDataPB, FlowyError> {
  83. let payload = data.into_inner();
  84. let document = convert_data_to_document_internal(payload)?;
  85. data_result_ok(document)
  86. }
  87. pub fn convert_data_to_document_internal(
  88. payload: ConvertDataPayloadPB,
  89. ) -> Result<DocumentDataPB, FlowyError> {
  90. let params: ConvertDataParams = payload.try_into()?;
  91. let convert_type = params.convert_type;
  92. let data = params.data;
  93. match convert_type {
  94. ConvertType::Json => {
  95. let json_str = String::from_utf8(data).map_err(|_| FlowyError::invalid_data())?;
  96. let document = JsonToDocumentParser::json_str_to_document(&json_str)?;
  97. Ok(document)
  98. },
  99. }
  100. }
  101. pub(crate) async fn redo_handler(
  102. data: AFPluginData<DocumentRedoUndoPayloadPB>,
  103. manager: AFPluginState<Weak<DocumentManager>>,
  104. ) -> DataResult<DocumentRedoUndoResponsePB, FlowyError> {
  105. let manager = upgrade_document(manager)?;
  106. let params: DocumentRedoUndoParams = data.into_inner().try_into()?;
  107. let doc_id = params.document_id;
  108. let document = manager.get_document(&doc_id).await?;
  109. let document = document.lock();
  110. let redo = document.redo();
  111. let can_redo = document.can_redo();
  112. let can_undo = document.can_undo();
  113. data_result_ok(DocumentRedoUndoResponsePB {
  114. can_redo,
  115. can_undo,
  116. is_success: redo,
  117. })
  118. }
  119. pub(crate) async fn undo_handler(
  120. data: AFPluginData<DocumentRedoUndoPayloadPB>,
  121. manager: AFPluginState<Weak<DocumentManager>>,
  122. ) -> DataResult<DocumentRedoUndoResponsePB, FlowyError> {
  123. let manager = upgrade_document(manager)?;
  124. let params: DocumentRedoUndoParams = data.into_inner().try_into()?;
  125. let doc_id = params.document_id;
  126. let document = manager.get_document(&doc_id).await?;
  127. let document = document.lock();
  128. let undo = document.undo();
  129. let can_redo = document.can_redo();
  130. let can_undo = document.can_undo();
  131. data_result_ok(DocumentRedoUndoResponsePB {
  132. can_redo,
  133. can_undo,
  134. is_success: undo,
  135. })
  136. }
  137. pub(crate) async fn can_undo_redo_handler(
  138. data: AFPluginData<DocumentRedoUndoPayloadPB>,
  139. manager: AFPluginState<Weak<DocumentManager>>,
  140. ) -> DataResult<DocumentRedoUndoResponsePB, FlowyError> {
  141. let manager = upgrade_document(manager)?;
  142. let params: DocumentRedoUndoParams = data.into_inner().try_into()?;
  143. let doc_id = params.document_id;
  144. let document = manager.get_document(&doc_id).await?;
  145. let document = document.lock();
  146. let can_redo = document.can_redo();
  147. let can_undo = document.can_undo();
  148. drop(document);
  149. data_result_ok(DocumentRedoUndoResponsePB {
  150. can_redo,
  151. can_undo,
  152. is_success: true,
  153. })
  154. }
  155. pub(crate) async fn get_snapshot_handler(
  156. data: AFPluginData<OpenDocumentPayloadPB>,
  157. manager: AFPluginState<Weak<DocumentManager>>,
  158. ) -> DataResult<RepeatedDocumentSnapshotPB, FlowyError> {
  159. let manager = upgrade_document(manager)?;
  160. let params: OpenDocumentParams = data.into_inner().try_into()?;
  161. let doc_id = params.document_id;
  162. let snapshots = manager.get_document_snapshots(&doc_id).await?;
  163. data_result_ok(RepeatedDocumentSnapshotPB { items: snapshots })
  164. }
  165. impl From<BlockActionPB> for BlockAction {
  166. fn from(pb: BlockActionPB) -> Self {
  167. Self {
  168. action: pb.action.into(),
  169. payload: pb.payload.into(),
  170. }
  171. }
  172. }
  173. impl From<BlockActionTypePB> for BlockActionType {
  174. fn from(pb: BlockActionTypePB) -> Self {
  175. match pb {
  176. BlockActionTypePB::Insert => Self::Insert,
  177. BlockActionTypePB::Update => Self::Update,
  178. BlockActionTypePB::Delete => Self::Delete,
  179. BlockActionTypePB::Move => Self::Move,
  180. }
  181. }
  182. }
  183. impl From<BlockActionPayloadPB> for BlockActionPayload {
  184. fn from(pb: BlockActionPayloadPB) -> Self {
  185. Self {
  186. block: pb.block.into(),
  187. parent_id: pb.parent_id,
  188. prev_id: pb.prev_id,
  189. }
  190. }
  191. }
  192. impl From<BlockPB> for Block {
  193. fn from(pb: BlockPB) -> Self {
  194. // Use `json_str_to_hashmap()` from the `collab_document` crate to convert the JSON data to a hashmap
  195. let data = json_str_to_hashmap(&pb.data).unwrap_or_default();
  196. // Convert the protobuf `BlockPB` to our internal `Block` struct
  197. Self {
  198. id: pb.id,
  199. ty: pb.ty,
  200. children: pb.children_id,
  201. parent: pb.parent_id,
  202. data,
  203. external_id: None,
  204. external_type: None,
  205. }
  206. }
  207. }
  208. impl From<BlockEvent> for BlockEventPB {
  209. fn from(payload: BlockEvent) -> Self {
  210. // Convert each individual `BlockEvent` to a protobuf `BlockEventPB`, and collect the results into a `Vec`
  211. Self {
  212. event: payload.iter().map(|e| e.to_owned().into()).collect(),
  213. }
  214. }
  215. }
  216. impl From<BlockEventPayload> for BlockEventPayloadPB {
  217. fn from(payload: BlockEventPayload) -> Self {
  218. Self {
  219. command: payload.command.into(),
  220. path: payload.path,
  221. id: payload.id,
  222. value: payload.value,
  223. }
  224. }
  225. }
  226. impl From<DeltaType> for DeltaTypePB {
  227. fn from(action: DeltaType) -> Self {
  228. match action {
  229. DeltaType::Inserted => Self::Inserted,
  230. DeltaType::Updated => Self::Updated,
  231. DeltaType::Removed => Self::Removed,
  232. }
  233. }
  234. }
  235. impl From<(&Vec<BlockEvent>, bool)> for DocEventPB {
  236. fn from((events, is_remote): (&Vec<BlockEvent>, bool)) -> Self {
  237. // Convert each individual `BlockEvent` to a protobuf `BlockEventPB`, and collect the results into a `Vec`
  238. Self {
  239. events: events.iter().map(|e| e.to_owned().into()).collect(),
  240. is_remote,
  241. }
  242. }
  243. }