controller.rs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. use bytes::Bytes;
  2. use chrono::Utc;
  3. use flowy_collaboration::client_document::default::{initial_delta, initial_read_me};
  4. use flowy_core_data_model::user_default;
  5. use flowy_sync::RevisionWebSocket;
  6. use lazy_static::lazy_static;
  7. use flowy_collaboration::{entities::ws_data::ServerRevisionWSData, folder::FolderPad};
  8. use flowy_document::FlowyDocumentManager;
  9. use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc};
  10. use tokio::sync::RwLock as TokioRwLock;
  11. use crate::{
  12. dart_notification::{send_dart_notification, WorkspaceNotification},
  13. entities::workspace::RepeatedWorkspace,
  14. errors::FlowyResult,
  15. module::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser},
  16. services::{
  17. folder_editor::FolderEditor,
  18. persistence::FolderPersistence,
  19. set_current_workspace,
  20. AppController,
  21. TrashController,
  22. ViewController,
  23. WorkspaceController,
  24. },
  25. };
  26. lazy_static! {
  27. static ref INIT_FOLDER_FLAG: TokioRwLock<HashMap<String, bool>> = TokioRwLock::new(HashMap::new());
  28. }
  29. const FOLDER_ID: &str = "folder";
  30. const FOLDER_ID_SPLIT: &str = ":";
  31. #[derive(Clone)]
  32. pub struct FolderId(String);
  33. impl FolderId {
  34. pub fn new(user_id: &str) -> Self { Self(format!("{}{}{}", user_id, FOLDER_ID_SPLIT, FOLDER_ID)) }
  35. }
  36. impl std::fmt::Display for FolderId {
  37. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(FOLDER_ID) }
  38. }
  39. impl std::fmt::Debug for FolderId {
  40. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(FOLDER_ID) }
  41. }
  42. impl AsRef<str> for FolderId {
  43. fn as_ref(&self) -> &str { &self.0 }
  44. }
  45. pub struct FolderManager {
  46. pub user: Arc<dyn WorkspaceUser>,
  47. pub(crate) cloud_service: Arc<dyn FolderCouldServiceV1>,
  48. pub(crate) persistence: Arc<FolderPersistence>,
  49. pub(crate) workspace_controller: Arc<WorkspaceController>,
  50. pub(crate) app_controller: Arc<AppController>,
  51. pub(crate) view_controller: Arc<ViewController>,
  52. pub(crate) trash_controller: Arc<TrashController>,
  53. web_socket: Arc<dyn RevisionWebSocket>,
  54. folder_editor: Arc<TokioRwLock<Option<Arc<FolderEditor>>>>,
  55. }
  56. impl FolderManager {
  57. pub async fn new(
  58. user: Arc<dyn WorkspaceUser>,
  59. cloud_service: Arc<dyn FolderCouldServiceV1>,
  60. database: Arc<dyn WorkspaceDatabase>,
  61. document_manager: Arc<FlowyDocumentManager>,
  62. web_socket: Arc<dyn RevisionWebSocket>,
  63. ) -> Self {
  64. let folder_editor = Arc::new(TokioRwLock::new(None));
  65. let persistence = Arc::new(FolderPersistence::new(database.clone(), folder_editor.clone()));
  66. let trash_controller = Arc::new(TrashController::new(
  67. persistence.clone(),
  68. cloud_service.clone(),
  69. user.clone(),
  70. ));
  71. let view_controller = Arc::new(ViewController::new(
  72. user.clone(),
  73. persistence.clone(),
  74. cloud_service.clone(),
  75. trash_controller.clone(),
  76. document_manager,
  77. ));
  78. let app_controller = Arc::new(AppController::new(
  79. user.clone(),
  80. persistence.clone(),
  81. trash_controller.clone(),
  82. cloud_service.clone(),
  83. ));
  84. let workspace_controller = Arc::new(WorkspaceController::new(
  85. user.clone(),
  86. persistence.clone(),
  87. trash_controller.clone(),
  88. cloud_service.clone(),
  89. ));
  90. Self {
  91. user,
  92. cloud_service,
  93. persistence,
  94. workspace_controller,
  95. app_controller,
  96. view_controller,
  97. trash_controller,
  98. web_socket,
  99. folder_editor,
  100. }
  101. }
  102. // pub fn network_state_changed(&self, new_type: NetworkType) {
  103. // match new_type {
  104. // NetworkType::UnknownNetworkType => {},
  105. // NetworkType::Wifi => {},
  106. // NetworkType::Cell => {},
  107. // NetworkType::Ethernet => {},
  108. // }
  109. // }
  110. pub async fn did_receive_ws_data(&self, data: Bytes) {
  111. let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into();
  112. match result {
  113. Ok(data) => match self.folder_editor.read().await.clone() {
  114. None => {},
  115. Some(editor) => match editor.receive_ws_data(data).await {
  116. Ok(_) => {},
  117. Err(e) => tracing::error!("Folder receive data error: {:?}", e),
  118. },
  119. },
  120. Err(e) => {
  121. tracing::error!("Folder ws data parser failed: {:?}", e);
  122. },
  123. }
  124. }
  125. pub async fn initialize(&self, user_id: &str, token: &str) -> FlowyResult<()> {
  126. let mut write_guard = INIT_FOLDER_FLAG.write().await;
  127. if let Some(is_init) = write_guard.get(user_id) {
  128. if *is_init {
  129. return Ok(());
  130. }
  131. }
  132. let folder_id = FolderId::new(user_id);
  133. let _ = self.persistence.initialize(user_id, &folder_id).await?;
  134. let pool = self.persistence.db_pool()?;
  135. let folder_editor = FolderEditor::new(user_id, &folder_id, token, pool, self.web_socket.clone()).await?;
  136. *self.folder_editor.write().await = Some(Arc::new(folder_editor));
  137. let _ = self.app_controller.initialize()?;
  138. let _ = self.view_controller.initialize()?;
  139. write_guard.insert(user_id.to_owned(), true);
  140. Ok(())
  141. }
  142. pub async fn initialize_with_new_user(&self, user_id: &str, token: &str) -> FlowyResult<()> {
  143. DefaultFolderBuilder::build(token, user_id, self.persistence.clone(), self.view_controller.clone()).await?;
  144. self.initialize(user_id, token).await
  145. }
  146. pub async fn clear(&self) { *self.folder_editor.write().await = None; }
  147. }
  148. struct DefaultFolderBuilder();
  149. impl DefaultFolderBuilder {
  150. async fn build(
  151. token: &str,
  152. user_id: &str,
  153. persistence: Arc<FolderPersistence>,
  154. view_controller: Arc<ViewController>,
  155. ) -> FlowyResult<()> {
  156. log::debug!("Create user default workspace");
  157. let time = Utc::now();
  158. let workspace = user_default::create_default_workspace(time);
  159. set_current_workspace(&workspace.id);
  160. for app in workspace.apps.iter() {
  161. for (index, view) in app.belongings.iter().enumerate() {
  162. let view_data = if index == 0 {
  163. initial_read_me().to_json()
  164. } else {
  165. initial_delta().to_json()
  166. };
  167. view_controller.set_latest_view(&view);
  168. let _ = view_controller
  169. .create_view_document_content(&view.id, view_data)
  170. .await?;
  171. }
  172. }
  173. let folder = FolderPad::new(vec![workspace.clone()], vec![])?;
  174. let folder_id = FolderId::new(user_id);
  175. let _ = persistence.save_folder(user_id, &folder_id, folder).await?;
  176. let repeated_workspace = RepeatedWorkspace { items: vec![workspace] };
  177. send_dart_notification(token, WorkspaceNotification::UserCreateWorkspace)
  178. .payload(repeated_workspace)
  179. .send();
  180. Ok(())
  181. }
  182. }
  183. #[cfg(feature = "flowy_unit_test")]
  184. impl FolderManager {
  185. pub async fn folder_editor(&self) -> Arc<FolderEditor> { self.folder_editor.read().await.clone().unwrap() }
  186. }