manager.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. use std::{collections::HashMap, sync::Arc};
  2. use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
  3. use appflowy_integrate::RocksCollabDB;
  4. use collab_document::blocks::DocumentData;
  5. use collab_document::YrsDocAction;
  6. use parking_lot::RwLock;
  7. use flowy_error::{FlowyError, FlowyResult};
  8. use crate::{
  9. document::Document,
  10. document_data::default_document_data,
  11. entities::DocEventPB,
  12. notification::{send_notification, DocumentNotification},
  13. };
  14. pub trait DocumentUser: Send + Sync {
  15. fn user_id(&self) -> Result<i64, FlowyError>;
  16. fn token(&self) -> Result<Option<String>, FlowyError>; // unused now.
  17. fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
  18. }
  19. pub struct DocumentManager {
  20. user: Arc<dyn DocumentUser>,
  21. collab_builder: Arc<AppFlowyCollabBuilder>,
  22. documents: Arc<RwLock<HashMap<String, Arc<Document>>>>,
  23. }
  24. impl DocumentManager {
  25. pub fn new(user: Arc<dyn DocumentUser>, collab_builder: Arc<AppFlowyCollabBuilder>) -> Self {
  26. Self {
  27. user,
  28. collab_builder,
  29. documents: Default::default(),
  30. }
  31. }
  32. /// Create a new document.
  33. ///
  34. /// if the document already exists, return the existing document.
  35. /// if the data is None, will create a document with default data.
  36. pub fn create_document(
  37. &self,
  38. doc_id: String,
  39. data: Option<DocumentData>,
  40. ) -> FlowyResult<Arc<Document>> {
  41. tracing::debug!("create a document: {:?}", &doc_id);
  42. let uid = self.user.user_id()?;
  43. let db = self.user.collab_db()?;
  44. let collab = self.collab_builder.build(uid, &doc_id, "document", db);
  45. let data = data.unwrap_or_else(default_document_data);
  46. let document = Arc::new(Document::create_with_data(collab, data)?);
  47. Ok(document)
  48. }
  49. pub fn open_document(&self, doc_id: String) -> FlowyResult<Arc<Document>> {
  50. if let Some(doc) = self.documents.read().get(&doc_id) {
  51. return Ok(doc.clone());
  52. }
  53. tracing::debug!("open_document: {:?}", &doc_id);
  54. let uid = self.user.user_id()?;
  55. let db = self.user.collab_db()?;
  56. let collab = self.collab_builder.build(uid, &doc_id, "document", db);
  57. // read the existing document from the disk.
  58. let document = Arc::new(Document::new(collab)?);
  59. // save the document to the memory and read it from the memory if we open the same document again.
  60. // and we don't want to subscribe to the document changes if we open the same document again.
  61. self
  62. .documents
  63. .write()
  64. .insert(doc_id.clone(), document.clone());
  65. // subscribe to the document changes.
  66. document.lock().open(move |events, is_remote| {
  67. tracing::trace!(
  68. "document changed: {:?}, from remote: {}",
  69. &events,
  70. is_remote
  71. );
  72. // send notification to the client.
  73. send_notification(&doc_id, DocumentNotification::DidReceiveUpdate)
  74. .payload::<DocEventPB>((events, is_remote).into())
  75. .send();
  76. })?;
  77. Ok(document)
  78. }
  79. pub fn get_document(&self, doc_id: String) -> FlowyResult<Arc<Document>> {
  80. let uid = self.user.user_id()?;
  81. let db = self.user.collab_db()?;
  82. let collab = self.collab_builder.build(uid, &doc_id, "document", db);
  83. // read the existing document from the disk.
  84. let document = Arc::new(Document::new(collab)?);
  85. Ok(document)
  86. }
  87. pub fn close_document(&self, doc_id: &str) -> FlowyResult<()> {
  88. self.documents.write().remove(doc_id);
  89. Ok(())
  90. }
  91. pub fn delete_document(&self, doc_id: &str) -> FlowyResult<()> {
  92. let uid = self.user.user_id()?;
  93. let db = self.user.collab_db()?;
  94. let _ = db.with_write_txn(|txn| {
  95. txn.delete_doc(uid, &doc_id)?;
  96. Ok(())
  97. });
  98. self.documents.write().remove(doc_id);
  99. Ok(())
  100. }
  101. }