AppFlowy/frontend/rust-lib/flowy-folder/src/manager.rs

225 lines
7.7 KiB
Rust
Raw Normal View History

2022-01-14 12:52:03 +00:00
use bytes::Bytes;
2021-12-13 05:55:44 +00:00
use chrono::Utc;
2022-03-05 02:59:44 +00:00
use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me};
use flowy_folder_data_model::user_default;
2022-01-14 12:52:03 +00:00
use flowy_sync::RevisionWebSocket;
2022-01-10 15:45:59 +00:00
use lazy_static::lazy_static;
2022-01-17 03:55:36 +00:00
use flowy_block::BlockManager;
use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData};
2022-01-23 14:33:47 +00:00
2022-02-28 08:00:43 +00:00
use flowy_collaboration::entities::revision::{RepeatedRevision, Revision};
2022-01-22 10:48:43 +00:00
use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc};
2022-01-20 15:51:11 +00:00
use tokio::sync::RwLock as TokioRwLock;
2021-12-13 05:55:44 +00:00
2021-12-06 07:49:21 +00:00
use crate::{
dart_notification::{send_dart_notification, FolderNotification},
2021-12-06 07:49:21 +00:00
entities::workspace::RepeatedWorkspace,
2022-01-18 14:56:57 +00:00
errors::FlowyResult,
2022-01-30 02:33:21 +00:00
event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser},
services::{
2022-02-26 03:03:42 +00:00
folder_editor::ClientFolderEditor, persistence::FolderPersistence, set_current_workspace, AppController,
2022-01-24 09:35:58 +00:00
TrashController, ViewController, WorkspaceController,
},
2021-12-06 07:49:21 +00:00
};
2021-12-13 05:55:44 +00:00
2021-12-06 07:49:21 +00:00
lazy_static! {
2022-01-23 14:33:47 +00:00
static ref INIT_FOLDER_FLAG: TokioRwLock<HashMap<String, bool>> = TokioRwLock::new(HashMap::new());
2021-12-06 07:49:21 +00:00
}
2022-01-23 14:33:47 +00:00
const FOLDER_ID: &str = "folder";
2022-01-22 10:48:43 +00:00
const FOLDER_ID_SPLIT: &str = ":";
#[derive(Clone)]
pub struct FolderId(String);
impl FolderId {
2022-01-24 09:35:58 +00:00
pub fn new(user_id: &str) -> Self {
Self(format!("{}{}{}", user_id, FOLDER_ID_SPLIT, FOLDER_ID))
}
2022-01-22 10:48:43 +00:00
}
impl std::fmt::Display for FolderId {
2022-01-24 09:35:58 +00:00
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(FOLDER_ID)
}
2022-01-22 10:48:43 +00:00
}
impl std::fmt::Debug for FolderId {
2022-01-24 09:35:58 +00:00
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(FOLDER_ID)
}
2022-01-22 10:48:43 +00:00
}
impl AsRef<str> for FolderId {
2022-01-24 09:35:58 +00:00
fn as_ref(&self) -> &str {
&self.0
}
2022-01-22 10:48:43 +00:00
}
2022-01-14 12:52:03 +00:00
pub struct FolderManager {
2021-12-06 07:49:21 +00:00
pub user: Arc<dyn WorkspaceUser>,
2022-01-17 03:55:36 +00:00
pub(crate) cloud_service: Arc<dyn FolderCouldServiceV1>,
pub(crate) persistence: Arc<FolderPersistence>,
2022-01-20 15:51:11 +00:00
pub(crate) workspace_controller: Arc<WorkspaceController>,
2021-12-06 07:49:21 +00:00
pub(crate) app_controller: Arc<AppController>,
pub(crate) view_controller: Arc<ViewController>,
pub(crate) trash_controller: Arc<TrashController>,
2022-01-20 15:51:11 +00:00
web_socket: Arc<dyn RevisionWebSocket>,
2022-02-26 03:03:42 +00:00
folder_editor: Arc<TokioRwLock<Option<Arc<ClientFolderEditor>>>>,
2021-12-06 07:49:21 +00:00
}
2022-01-14 12:52:03 +00:00
impl FolderManager {
2022-01-23 14:33:47 +00:00
pub async fn new(
2021-12-06 07:49:21 +00:00
user: Arc<dyn WorkspaceUser>,
2022-01-17 03:55:36 +00:00
cloud_service: Arc<dyn FolderCouldServiceV1>,
2022-01-20 15:51:11 +00:00
database: Arc<dyn WorkspaceDatabase>,
block_manager: Arc<BlockManager>,
2022-01-20 15:51:11 +00:00
web_socket: Arc<dyn RevisionWebSocket>,
2021-12-06 07:49:21 +00:00
) -> Self {
if let Ok(user_id) = user.user_id() {
// Reset the flag if the folder manager gets initialized, otherwise,
// the folder_editor will not be initialized after flutter hot reload.
INIT_FOLDER_FLAG.write().await.insert(user_id.to_owned(), false);
}
2022-01-20 15:51:11 +00:00
let folder_editor = Arc::new(TokioRwLock::new(None));
let persistence = Arc::new(FolderPersistence::new(database.clone(), folder_editor.clone()));
2022-01-14 12:52:03 +00:00
let trash_controller = Arc::new(TrashController::new(
persistence.clone(),
cloud_service.clone(),
user.clone(),
));
let view_controller = Arc::new(ViewController::new(
user.clone(),
persistence.clone(),
cloud_service.clone(),
trash_controller.clone(),
block_manager,
2022-01-14 12:52:03 +00:00
));
let app_controller = Arc::new(AppController::new(
user.clone(),
persistence.clone(),
trash_controller.clone(),
cloud_service.clone(),
));
let workspace_controller = Arc::new(WorkspaceController::new(
user.clone(),
persistence.clone(),
trash_controller.clone(),
cloud_service.clone(),
));
2021-12-06 07:49:21 +00:00
Self {
user,
2022-01-10 15:45:59 +00:00
cloud_service,
2022-01-14 01:09:25 +00:00
persistence,
2021-12-06 07:49:21 +00:00
workspace_controller,
app_controller,
view_controller,
trash_controller,
2022-01-20 15:51:11 +00:00
web_socket,
folder_editor,
2021-12-06 07:49:21 +00:00
}
}
2022-01-10 15:45:59 +00:00
// pub fn network_state_changed(&self, new_type: NetworkType) {
// match new_type {
// NetworkType::UnknownNetworkType => {},
// NetworkType::Wifi => {},
// NetworkType::Cell => {},
// NetworkType::Ethernet => {},
// }
// }
2021-12-06 07:49:21 +00:00
2022-01-20 15:51:11 +00:00
pub async fn did_receive_ws_data(&self, data: Bytes) {
let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into();
match result {
Ok(data) => match self.folder_editor.read().await.clone() {
2022-01-24 09:35:58 +00:00
None => {}
2022-01-20 15:51:11 +00:00
Some(editor) => match editor.receive_ws_data(data).await {
2022-01-24 09:35:58 +00:00
Ok(_) => {}
2022-01-20 15:51:11 +00:00
Err(e) => tracing::error!("Folder receive data error: {:?}", e),
},
},
Err(e) => {
tracing::error!("Folder ws data parser failed: {:?}", e);
2022-01-24 09:35:58 +00:00
}
2022-01-20 15:51:11 +00:00
}
}
2022-01-14 12:52:03 +00:00
#[tracing::instrument(level = "trace", skip(self), err)]
2022-01-24 08:27:40 +00:00
pub async fn initialize(&self, user_id: &str, token: &str) -> FlowyResult<()> {
2022-01-23 14:33:47 +00:00
let mut write_guard = INIT_FOLDER_FLAG.write().await;
if let Some(is_init) = write_guard.get(user_id) {
2022-01-18 14:56:57 +00:00
if *is_init {
return Ok(());
}
}
tracing::debug!("Initialize folder editor");
2022-01-22 10:48:43 +00:00
let folder_id = FolderId::new(user_id);
let _ = self.persistence.initialize(user_id, &folder_id).await?;
2022-01-20 15:51:11 +00:00
let pool = self.persistence.db_pool()?;
2022-02-26 03:03:42 +00:00
let folder_editor = ClientFolderEditor::new(user_id, &folder_id, token, pool, self.web_socket.clone()).await?;
2022-01-20 15:51:11 +00:00
*self.folder_editor.write().await = Some(Arc::new(folder_editor));
2022-01-18 14:56:57 +00:00
let _ = self.app_controller.initialize()?;
let _ = self.view_controller.initialize()?;
2022-01-23 14:33:47 +00:00
write_guard.insert(user_id.to_owned(), true);
2022-01-18 14:56:57 +00:00
Ok(())
}
2021-12-06 07:49:21 +00:00
pub async fn initialize_with_new_user(&self, user_id: &str, token: &str) -> FlowyResult<()> {
DefaultFolderBuilder::build(token, user_id, self.persistence.clone(), self.view_controller.clone()).await?;
2022-01-24 08:27:40 +00:00
self.initialize(user_id, token).await
}
2022-01-24 09:35:58 +00:00
pub async fn clear(&self) {
*self.folder_editor.write().await = None;
}
}
struct DefaultFolderBuilder();
impl DefaultFolderBuilder {
async fn build(
token: &str,
user_id: &str,
persistence: Arc<FolderPersistence>,
view_controller: Arc<ViewController>,
) -> FlowyResult<()> {
2021-12-06 07:49:21 +00:00
log::debug!("Create user default workspace");
let time = Utc::now();
2022-01-18 14:56:57 +00:00
let workspace = user_default::create_default_workspace(time);
set_current_workspace(&workspace.id);
for app in workspace.apps.iter() {
for (index, view) in app.belongings.iter().enumerate() {
2021-12-28 16:34:00 +00:00
let view_data = if index == 0 {
2022-03-01 15:38:26 +00:00
initial_read_me().to_delta_json()
2021-12-28 16:34:00 +00:00
} else {
2022-03-05 02:59:44 +00:00
initial_quill_delta_string()
2021-12-28 16:34:00 +00:00
};
2022-01-24 09:35:58 +00:00
view_controller.set_latest_view(view);
2022-03-05 02:59:44 +00:00
let _ = view_controller.create_view(&view.id, Bytes::from(view_data)).await?;
2021-12-06 07:49:21 +00:00
}
}
let folder = FolderPad::new(vec![workspace.clone()], vec![])?;
2022-01-22 10:48:43 +00:00
let folder_id = FolderId::new(user_id);
let _ = persistence.save_folder(user_id, &folder_id, folder).await?;
let repeated_workspace = RepeatedWorkspace { items: vec![workspace] };
send_dart_notification(token, FolderNotification::UserCreateWorkspace)
2021-12-06 07:49:21 +00:00
.payload(repeated_workspace)
.send();
2021-12-06 13:47:21 +00:00
Ok(())
}
2021-12-06 07:49:21 +00:00
}
2022-01-22 10:48:43 +00:00
#[cfg(feature = "flowy_unit_test")]
impl FolderManager {
2022-02-26 03:03:42 +00:00
pub async fn folder_editor(&self) -> Arc<ClientFolderEditor> {
2022-01-24 09:35:58 +00:00
self.folder_editor.read().await.clone().unwrap()
}
2022-01-22 10:48:43 +00:00
}