controller.rs 7.9 KB

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