diff --git a/frontend/appflowy_tauri/src-tauri/src/request.rs b/frontend/appflowy_tauri/src-tauri/src/request.rs index 6d2d01fb6e..146d303cc0 100644 --- a/frontend/appflowy_tauri/src-tauri/src/request.rs +++ b/frontend/appflowy_tauri/src-tauri/src/request.rs @@ -1,4 +1,4 @@ -use flowy_core::MutexAppFlowyCore; +use flowy_core::; use lib_dispatch::prelude::{ AFPluginDispatcher, AFPluginEventResponse, AFPluginRequest, StatusCode, }; diff --git a/frontend/appflowy_web_app/src-tauri/src/request.rs b/frontend/appflowy_web_app/src-tauri/src/request.rs index 0ec6a8dadc..6d2d01fb6e 100644 --- a/frontend/appflowy_web_app/src-tauri/src/request.rs +++ b/frontend/appflowy_web_app/src-tauri/src/request.rs @@ -1,4 +1,4 @@ -use flowy_core::{AppFlowyCore, MutexAppFlowyCore}; +use flowy_core::MutexAppFlowyCore; use lib_dispatch::prelude::{ AFPluginDispatcher, AFPluginEventResponse, AFPluginRequest, StatusCode, }; diff --git a/frontend/rust-lib/flowy-ai-pub/src/cloud.rs b/frontend/rust-lib/flowy-ai-pub/src/cloud.rs index 30f29d6c7f..918477b634 100644 --- a/frontend/rust-lib/flowy-ai-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-ai-pub/src/cloud.rs @@ -11,7 +11,6 @@ use client_api::error::AppResponseError; use flowy_error::FlowyError; use futures::stream::BoxStream; use lib_infra::async_trait::async_trait; -use lib_infra::future::FutureResult; use serde_json::Value; use std::collections::HashMap; use std::path::Path; @@ -21,12 +20,12 @@ pub type StreamAnswer = BoxStream<'static, Result>; #[async_trait] pub trait ChatCloudService: Send + Sync + 'static { - fn create_chat( + async fn create_chat( &self, uid: &i64, workspace_id: &str, chat_id: &str, - ) -> FutureResult<(), FlowyError>; + ) -> Result<(), FlowyError>; async fn create_question( &self, diff --git a/frontend/rust-lib/flowy-ai/src/event_handler.rs b/frontend/rust-lib/flowy-ai/src/event_handler.rs index 3ec6eeb660..99933456f5 100644 --- a/frontend/rust-lib/flowy-ai/src/event_handler.rs +++ b/frontend/rust-lib/flowy-ai/src/event_handler.rs @@ -14,7 +14,6 @@ use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; use lib_infra::isolate_stream::IsolateSink; use std::sync::{Arc, Weak}; -use tokio::sync::oneshot; use tracing::trace; use validator::Validate; @@ -114,15 +113,9 @@ pub(crate) async fn get_related_question_handler( ) -> DataResult { let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); - let (tx, rx) = tokio::sync::oneshot::channel(); - tokio::spawn(async move { - let messages = ai_manager - .get_related_questions(&data.chat_id, data.message_id) - .await?; - let _ = tx.send(messages); - Ok::<_, FlowyError>(()) - }); - let messages = rx.await?; + let messages = ai_manager + .get_related_questions(&data.chat_id, data.message_id) + .await?; data_result_ok(messages) } @@ -133,15 +126,9 @@ pub(crate) async fn get_answer_handler( ) -> DataResult { let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); - let (tx, rx) = tokio::sync::oneshot::channel(); - tokio::spawn(async move { - let message = ai_manager - .generate_answer(&data.chat_id, data.message_id) - .await?; - let _ = tx.send(message); - Ok::<_, FlowyError>(()) - }); - let message = rx.await?; + let message = ai_manager + .generate_answer(&data.chat_id, data.message_id) + .await?; data_result_ok(message) } @@ -163,25 +150,17 @@ pub(crate) async fn refresh_local_ai_info_handler( ai_manager: AFPluginState>, ) -> DataResult { let ai_manager = upgrade_ai_manager(ai_manager)?; - let (tx, rx) = oneshot::channel::>(); - tokio::spawn(async move { - let model_info = ai_manager.local_ai_controller.refresh().await; - if model_info.is_err() { - if let Some(llm_model) = ai_manager.local_ai_controller.get_current_model() { - let model_info = LLMModelInfo { - selected_model: llm_model.clone(), - models: vec![llm_model], - }; - let _ = tx.send(Ok(model_info)); - return; - } + let model_info = ai_manager.local_ai_controller.refresh().await; + if model_info.is_err() { + if let Some(llm_model) = ai_manager.local_ai_controller.get_current_model() { + let model_info = LLMModelInfo { + selected_model: llm_model.clone(), + models: vec![llm_model], + }; + return data_result_ok(model_info.into()); } - - let _ = tx.send(model_info); - }); - - let model_info = rx.await??; - data_result_ok(model_info.into()) + } + data_result_ok(model_info?.into()) } #[tracing::instrument(level = "debug", skip_all, err)] @@ -268,16 +247,9 @@ pub(crate) async fn chat_file_handler( } tracing::debug!("File size: {} bytes", file_size); - - let (tx, rx) = oneshot::channel::>(); - tokio::spawn(async move { - let ai_manager = upgrade_ai_manager(ai_manager)?; - ai_manager.chat_with_file(&data.chat_id, file_path).await?; - let _ = tx.send(Ok(())); - Ok::<_, FlowyError>(()) - }); - - rx.await? + let ai_manager = upgrade_ai_manager(ai_manager)?; + ai_manager.chat_with_file(&data.chat_id, file_path).await?; + Ok(()) } #[tracing::instrument(level = "debug", skip_all, err)] @@ -420,17 +392,10 @@ pub(crate) async fn get_offline_app_handler( ai_manager: AFPluginState>, ) -> DataResult { let ai_manager = upgrade_ai_manager(ai_manager)?; - let (tx, rx) = oneshot::channel::>(); - tokio::spawn(async move { - let link = ai_manager - .local_ai_controller - .get_offline_ai_app_download_link() - .await?; - let _ = tx.send(Ok(link)); - Ok::<_, FlowyError>(()) - }); - - let link = rx.await??; + let link = ai_manager + .local_ai_controller + .get_offline_ai_app_download_link() + .await?; data_result_ok(OfflineAIPB { link }) } diff --git a/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs b/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs index 598d5716c6..c2e46b3a80 100644 --- a/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs +++ b/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs @@ -14,7 +14,6 @@ use flowy_ai_pub::cloud::{ use flowy_error::{FlowyError, FlowyResult}; use futures::{stream, Sink, StreamExt, TryStreamExt}; use lib_infra::async_trait::async_trait; -use lib_infra::future::FutureResult; use crate::local_ai::stream_util::QuestionStream; use crate::stream_message::StreamMessage; @@ -108,13 +107,16 @@ impl AICloudServiceMiddleware { #[async_trait] impl ChatCloudService for AICloudServiceMiddleware { - fn create_chat( + async fn create_chat( &self, uid: &i64, workspace_id: &str, chat_id: &str, - ) -> FutureResult<(), FlowyError> { - self.cloud_service.create_chat(uid, workspace_id, chat_id) + ) -> Result<(), FlowyError> { + self + .cloud_service + .create_chat(uid, workspace_id, chat_id) + .await } async fn create_question( diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 6b6b22fa9d..78994e8a34 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -26,7 +26,7 @@ use flowy_sqlite::kv::KVStorePreferences; use flowy_user::services::authenticate_user::AuthenticateUser; use flowy_user::services::data_import::{load_collab_by_object_id, load_collab_by_object_ids}; use lib_dispatch::prelude::ToBytes; -use lib_infra::future::FutureResult; + use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{Arc, Weak}; @@ -35,6 +35,7 @@ use tokio::sync::RwLock; use crate::integrate::server::ServerProvider; use collab_plugins::local_storage::kv::KVTransactionDB; +use lib_infra::async_trait::async_trait; pub struct FolderDepsResolver(); #[allow(clippy::too_many_arguments)] @@ -113,363 +114,305 @@ impl FolderUser for FolderUserImpl { } struct DocumentFolderOperation(Arc); +#[async_trait] impl FolderOperationHandler for DocumentFolderOperation { - fn create_workspace_view( + async fn create_workspace_view( &self, uid: i64, workspace_view_builder: Arc>, - ) -> FutureResult<(), FlowyError> { + ) -> Result<(), FlowyError> { let manager = self.0.clone(); - FutureResult::new(async move { - let mut write_guard = workspace_view_builder.write().await; - - // Create a view named "Getting started" with an icon ⭐️ and the built-in README data. - // Don't modify this code unless you know what you are doing. - write_guard - .with_view_builder(|view_builder| async { - let view = view_builder - .with_name("Getting started") - .with_icon("⭐️") - .build(); - // create a empty document - let json_str = include_str!("../../assets/read_me.json"); - let document_pb = JsonToDocumentParser::json_str_to_document(json_str).unwrap(); - manager - .create_document(uid, &view.parent_view.id, Some(document_pb.into())) - .await - .unwrap(); - view - }) - .await; - Ok(()) - }) + let mut write_guard = workspace_view_builder.write().await; + // Create a view named "Getting started" with an icon ⭐️ and the built-in README data. + // Don't modify this code unless you know what you are doing. + write_guard + .with_view_builder(|view_builder| async { + let view = view_builder + .with_name("Getting started") + .with_icon("⭐️") + .build(); + // create a empty document + let json_str = include_str!("../../assets/read_me.json"); + let document_pb = JsonToDocumentParser::json_str_to_document(json_str).unwrap(); + manager + .create_document(uid, &view.parent_view.id, Some(document_pb.into())) + .await + .unwrap(); + view + }) + .await; + Ok(()) } - fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - manager.open_document(&view_id).await?; - Ok(()) - }) + async fn open_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.open_document(view_id).await?; + Ok(()) } /// Close the document view. - fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - manager.close_document(&view_id).await?; - Ok(()) - }) + async fn close_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.close_document(view_id).await?; + Ok(()) } - fn delete_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - match manager.delete_document(&view_id).await { - Ok(_) => tracing::trace!("Delete document: {}", view_id), - Err(e) => tracing::error!("🔴delete document failed: {}", e), - } - Ok(()) - }) + async fn delete_view(&self, view_id: &str) -> Result<(), FlowyError> { + match self.0.delete_document(view_id).await { + Ok(_) => tracing::trace!("Delete document: {}", view_id), + Err(e) => tracing::error!("🔴delete document failed: {}", e), + } + Ok(()) } - fn duplicate_view(&self, view_id: &str) -> FutureResult { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - let data: DocumentDataPB = manager.get_document_data(&view_id).await?.into(); - let data_bytes = data.into_bytes().map_err(|_| FlowyError::invalid_data())?; - Ok(data_bytes) - }) + async fn duplicate_view(&self, view_id: &str) -> Result { + let data: DocumentDataPB = self.0.get_document_data(view_id).await?.into(); + let data_bytes = data.into_bytes().map_err(|_| FlowyError::invalid_data())?; + Ok(data_bytes) } - fn create_view_with_view_data( + async fn create_view_with_view_data( &self, user_id: i64, params: CreateViewParams, - ) -> FutureResult, FlowyError> { + ) -> Result, FlowyError> { debug_assert_eq!(params.layout, ViewLayoutPB::Document); - let view_id = params.view_id.to_string(); - let manager = self.0.clone(); - FutureResult::new(async move { - let data = DocumentDataPB::try_from(Bytes::from(params.initial_data))?; - let encoded_collab = manager - .create_document(user_id, &view_id, Some(data.into())) - .await?; - Ok(Some(encoded_collab)) - }) + let data = DocumentDataPB::try_from(Bytes::from(params.initial_data))?; + let encoded_collab = self + .0 + .create_document(user_id, ¶ms.view_id, Some(data.into())) + .await?; + Ok(Some(encoded_collab)) } - fn get_encoded_collab_v1_from_disk( + async fn get_encoded_collab_v1_from_disk( &self, user: Arc, view_id: &str, - ) -> FutureResult { + ) -> Result { // get the collab_object_id for the document. // the collab_object_id for the document is the view_id. - let oid = view_id.to_string(); - FutureResult::new(async move { - let uid = user - .user_id() - .map_err(|e| e.with_context("unable to get the uid: {}"))?; + let uid = user + .user_id() + .map_err(|e| e.with_context("unable to get the uid: {}"))?; - // get the collab db - let collab_db = user - .collab_db(uid) - .map_err(|e| e.with_context("unable to get the collab"))?; - let collab_db = collab_db.upgrade().ok_or_else(|| { - FlowyError::internal().with_context( - "The collab db has been dropped, indicating that the user has switched to a new account", - ) - })?; - let collab_read_txn = collab_db.read_txn(); + // get the collab db + let collab_db = user + .collab_db(uid) + .map_err(|e| e.with_context("unable to get the collab"))?; + let collab_db = collab_db.upgrade().ok_or_else(|| { + FlowyError::internal().with_context( + "The collab db has been dropped, indicating that the user has switched to a new account", + ) + })?; + let collab_read_txn = collab_db.read_txn(); - // read the collab from the db - let collab = load_collab_by_object_id(uid, &collab_read_txn, &oid).map_err(|e| { - FlowyError::internal().with_context(format!("load document collab failed: {}", e)) - })?; + // read the collab from the db + let collab = load_collab_by_object_id(uid, &collab_read_txn, view_id).map_err(|e| { + FlowyError::internal().with_context(format!("load document collab failed: {}", e)) + })?; - let encoded_collab = collab + let encoded_collab = collab // encode the collab and check the integrity of the collab .encode_collab_v1(|collab| CollabType::Document.validate_require_data(collab)) .map_err(|e| { FlowyError::internal().with_context(format!("encode document collab failed: {}", e)) })?; - Ok(EncodedCollabWrapper::Document(DocumentEncodedCollab { - document_encoded_collab: encoded_collab, - })) - }) + Ok(EncodedCollabWrapper::Document(DocumentEncodedCollab { + document_encoded_collab: encoded_collab, + })) } /// Create a view with built-in data. - fn create_built_in_view( + async fn create_built_in_view( &self, user_id: i64, view_id: &str, _name: &str, layout: ViewLayout, - ) -> FutureResult<(), FlowyError> { + ) -> Result<(), FlowyError> { debug_assert_eq!(layout, ViewLayout::Document); - let view_id = view_id.to_string(); - let manager = self.0.clone(); - FutureResult::new(async move { - match manager.create_document(user_id, &view_id, None).await { - Ok(_) => Ok(()), - Err(err) => { - if err.is_already_exists() { - Ok(()) - } else { - Err(err) - } - }, - } - }) + match self.0.create_document(user_id, view_id, None).await { + Ok(_) => Ok(()), + Err(err) => { + if err.is_already_exists() { + Ok(()) + } else { + Err(err) + } + }, + } } - fn import_from_bytes( + async fn import_from_bytes( &self, uid: i64, view_id: &str, _name: &str, _import_type: ImportType, bytes: Vec, - ) -> FutureResult { - let view_id = view_id.to_string(); - let manager = self.0.clone(); - FutureResult::new(async move { - let data = DocumentDataPB::try_from(Bytes::from(bytes))?; - let encoded_collab = manager - .create_document(uid, &view_id, Some(data.into())) - .await?; - Ok(encoded_collab) - }) + ) -> Result { + let data = DocumentDataPB::try_from(Bytes::from(bytes))?; + let encoded_collab = self + .0 + .create_document(uid, view_id, Some(data.into())) + .await?; + Ok(encoded_collab) } // will implement soon - fn import_from_file_path( + async fn import_from_file_path( &self, _view_id: &str, _name: &str, _path: String, - ) -> FutureResult<(), FlowyError> { - FutureResult::new(async move { Ok(()) }) + ) -> Result<(), FlowyError> { + Ok(()) } } struct DatabaseFolderOperation(Arc); + +#[async_trait] impl FolderOperationHandler for DatabaseFolderOperation { - fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let database_manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - database_manager.open_database_view(view_id).await?; - Ok(()) - }) + async fn open_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.open_database_view(view_id).await?; + Ok(()) } - fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let database_manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - database_manager.close_database_view(view_id).await?; - Ok(()) - }) + async fn close_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.close_database_view(view_id).await?; + Ok(()) } - fn delete_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let database_manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - match database_manager.delete_database_view(&view_id).await { - Ok(_) => tracing::trace!("Delete database view: {}", view_id), - Err(e) => tracing::error!("🔴delete database failed: {}", e), - } - Ok(()) - }) + async fn delete_view(&self, view_id: &str) -> Result<(), FlowyError> { + match self.0.delete_database_view(view_id).await { + Ok(_) => tracing::trace!("Delete database view: {}", view_id), + Err(e) => tracing::error!("🔴delete database failed: {}", e), + } + Ok(()) } - fn get_encoded_collab_v1_from_disk( + async fn get_encoded_collab_v1_from_disk( &self, user: Arc, view_id: &str, - ) -> FutureResult { - let manager = self.0.clone(); - let view_id = view_id.to_string(); + ) -> Result { + // get the collab_object_id for the database. + // + // the collab object_id for the database is not the view_id, + // we should use the view_id to get the database_id + let oid = self.0.get_database_id_with_view_id(view_id).await?; + let row_oids = self.0.get_database_row_ids_with_view_id(view_id).await?; + let row_oids = row_oids + .into_iter() + .map(|oid| oid.into_inner()) + .collect::>(); + let database_metas = self.0.get_all_databases_meta().await; - FutureResult::new(async move { - // get the collab_object_id for the database. - // - // the collab object_id for the database is not the view_id, - // we should use the view_id to get the database_id - let oid = manager.get_database_id_with_view_id(&view_id).await?; - let row_oids = manager.get_database_row_ids_with_view_id(&view_id).await?; - let row_oids = row_oids - .into_iter() - .map(|oid| oid.into_inner()) - .collect::>(); - let database_metas = manager.get_all_databases_meta().await; + let uid = user + .user_id() + .map_err(|e| e.with_context("unable to get the uid: {}"))?; - let uid = user - .user_id() - .map_err(|e| e.with_context("unable to get the uid: {}"))?; + // get the collab db + let collab_db = user + .collab_db(uid) + .map_err(|e| e.with_context("unable to get the collab"))?; + let collab_db = collab_db.upgrade().ok_or_else(|| { + FlowyError::internal().with_context( + "The collab db has been dropped, indicating that the user has switched to a new account", + ) + })?; - // get the collab db - let collab_db = user - .collab_db(uid) - .map_err(|e| e.with_context("unable to get the collab"))?; - let collab_db = collab_db.upgrade().ok_or_else(|| { - FlowyError::internal().with_context( - "The collab db has been dropped, indicating that the user has switched to a new account", - ) - })?; + let collab_read_txn = collab_db.read_txn(); - let collab_read_txn = collab_db.read_txn(); + // read the database collab from the db + let database_collab = load_collab_by_object_id(uid, &collab_read_txn, &oid).map_err(|e| { + FlowyError::internal().with_context(format!("load database collab failed: {}", e)) + })?; - // read the database collab from the db - let database_collab = load_collab_by_object_id(uid, &collab_read_txn, &oid).map_err(|e| { - FlowyError::internal().with_context(format!("load database collab failed: {}", e)) - })?; - - let database_encoded_collab = database_collab + let database_encoded_collab = database_collab // encode the collab and check the integrity of the collab .encode_collab_v1(|collab| CollabType::Database.validate_require_data(collab)) .map_err(|e| { FlowyError::internal().with_context(format!("encode database collab failed: {}", e)) })?; - // read the database rows collab from the db - let database_row_collabs = load_collab_by_object_ids(uid, &collab_read_txn, &row_oids); - let database_row_encoded_collabs = database_row_collabs - .into_iter() - .map(|(oid, collab)| { - // encode the collab and check the integrity of the collab - let encoded_collab = collab - .encode_collab_v1(|collab| CollabType::DatabaseRow.validate_require_data(collab)) - .map_err(|e| { - FlowyError::internal() - .with_context(format!("encode database row collab failed: {}", e)) - })?; - Ok((oid, encoded_collab)) - }) - .collect::, FlowyError>>()?; + // read the database rows collab from the db + let database_row_collabs = load_collab_by_object_ids(uid, &collab_read_txn, &row_oids); + let database_row_encoded_collabs = database_row_collabs + .into_iter() + .map(|(oid, collab)| { + // encode the collab and check the integrity of the collab + let encoded_collab = collab + .encode_collab_v1(|collab| CollabType::DatabaseRow.validate_require_data(collab)) + .map_err(|e| { + FlowyError::internal().with_context(format!("encode database row collab failed: {}", e)) + })?; + Ok((oid, encoded_collab)) + }) + .collect::, FlowyError>>()?; - // get the relation info from the database meta - let database_relations = database_metas - .into_iter() - .filter_map(|meta| { - let linked_views = meta.linked_views.into_iter().next()?; - Some((meta.database_id, linked_views)) - }) - .collect::>(); + // get the relation info from the database meta + let database_relations = database_metas + .into_iter() + .filter_map(|meta| { + let linked_views = meta.linked_views.into_iter().next()?; + Some((meta.database_id, linked_views)) + }) + .collect::>(); - Ok(EncodedCollabWrapper::Database(DatabaseEncodedCollab { - database_encoded_collab, - database_row_encoded_collabs, - database_relations, - })) - }) + Ok(EncodedCollabWrapper::Database(DatabaseEncodedCollab { + database_encoded_collab, + database_row_encoded_collabs, + database_relations, + })) } - fn duplicate_view(&self, view_id: &str) -> FutureResult { - let database_manager = self.0.clone(); - let view_id = view_id.to_owned(); - FutureResult::new(async move { - let delta_bytes = database_manager.duplicate_database(&view_id).await?; - Ok(Bytes::from(delta_bytes)) - }) + async fn duplicate_view(&self, view_id: &str) -> Result { + let delta_bytes = self.0.duplicate_database(view_id).await?; + Ok(Bytes::from(delta_bytes)) } /// Create a database view with duplicated data. /// If the ext contains the {"database_id": "xx"}, then it will link /// to the existing database. - fn create_view_with_view_data( + async fn create_view_with_view_data( &self, _user_id: i64, params: CreateViewParams, - ) -> FutureResult, FlowyError> { + ) -> Result, FlowyError> { match CreateDatabaseExtParams::from_map(params.meta.clone()) { None => { - let database_manager = self.0.clone(); - let view_id = params.view_id.to_string(); - FutureResult::new(async move { - let encoded_collab = database_manager - .create_database_with_database_data(&view_id, params.initial_data) - .await?; - Ok(Some(encoded_collab)) - }) + let encoded_collab = self + .0 + .create_database_with_database_data(¶ms.view_id, params.initial_data) + .await?; + Ok(Some(encoded_collab)) }, Some(database_params) => { - let database_manager = self.0.clone(); - let layout = match params.layout { ViewLayoutPB::Board => DatabaseLayoutPB::Board, ViewLayoutPB::Calendar => DatabaseLayoutPB::Calendar, ViewLayoutPB::Grid => DatabaseLayoutPB::Grid, ViewLayoutPB::Document | ViewLayoutPB::Chat => { - return FutureResult::new(async move { Err(FlowyError::not_support()) }); + return Err(FlowyError::not_support()); }, }; let name = params.name.to_string(); let database_view_id = params.view_id.to_string(); let database_parent_view_id = params.parent_view_id.to_string(); - - FutureResult::new(async move { - database_manager - .create_linked_view( - name, - layout.into(), - database_params.database_id, - database_view_id, - database_parent_view_id, - ) - .await?; - Ok(None) - }) + self + .0 + .create_linked_view( + name, + layout.into(), + database_params.database_id, + database_view_id, + database_parent_view_id, + ) + .await?; + Ok(None) }, } } @@ -478,110 +421,90 @@ impl FolderOperationHandler for DatabaseFolderOperation { /// If the ext contains the {"database_id": "xx"}, then it will link to /// the existing database. The data of the database will be shared within /// these references views. - fn create_built_in_view( + async fn create_built_in_view( &self, _user_id: i64, view_id: &str, name: &str, layout: ViewLayout, - ) -> FutureResult<(), FlowyError> { + ) -> Result<(), FlowyError> { let name = name.to_string(); - let database_manager = self.0.clone(); let data = match layout { ViewLayout::Grid => make_default_grid(view_id, &name), ViewLayout::Board => make_default_board(view_id, &name), ViewLayout::Calendar => make_default_calendar(view_id, &name), - ViewLayout::Document => { - return FutureResult::new(async move { - Err(FlowyError::internal().with_context(format!("Can't handle {:?} layout type", layout))) - }); - }, - ViewLayout::Chat => { - // TODO(nathan): AI - todo!("AI") + ViewLayout::Document | ViewLayout::Chat => { + return Err( + FlowyError::internal().with_context(format!("Can't handle {:?} layout type", layout)), + ); }, }; - FutureResult::new(async move { - let result = database_manager.create_database_with_params(data).await; - match result { - Ok(_) => Ok(()), - Err(err) => { - if err.is_already_exists() { - Ok(()) - } else { - Err(err) - } - }, - } - }) + let result = self.0.create_database_with_params(data).await; + match result { + Ok(_) => Ok(()), + Err(err) => { + if err.is_already_exists() { + Ok(()) + } else { + Err(err) + } + }, + } } - fn import_from_bytes( + async fn import_from_bytes( &self, _uid: i64, view_id: &str, _name: &str, import_type: ImportType, bytes: Vec, - ) -> FutureResult { - let database_manager = self.0.clone(); - let view_id = view_id.to_string(); + ) -> Result { let format = match import_type { ImportType::CSV => CSVFormat::Original, ImportType::HistoryDatabase => CSVFormat::META, ImportType::RawDatabase => CSVFormat::META, _ => CSVFormat::Original, }; - FutureResult::new(async move { - let content = tokio::task::spawn_blocking(move || { - String::from_utf8(bytes).map_err(|err| FlowyError::internal().with_context(err)) - }) - .await??; - let result = database_manager - .import_csv(view_id, content, format) - .await?; - Ok(result.encoded_collab) + let content = tokio::task::spawn_blocking(move || { + String::from_utf8(bytes).map_err(|err| FlowyError::internal().with_context(err)) }) + .await??; + let result = self + .0 + .import_csv(view_id.to_string(), content, format) + .await?; + Ok(result.encoded_collab) } - fn import_from_file_path( + async fn import_from_file_path( &self, _view_id: &str, _name: &str, path: String, - ) -> FutureResult<(), FlowyError> { - let database_manager = self.0.clone(); - FutureResult::new(async move { - database_manager - .import_csv_from_file(path, CSVFormat::META) - .await?; - Ok(()) - }) + ) -> Result<(), FlowyError> { + self.0.import_csv_from_file(path, CSVFormat::META).await?; + Ok(()) } - fn did_update_view(&self, old: &View, new: &View) -> FutureResult<(), FlowyError> { + async fn did_update_view(&self, old: &View, new: &View) -> Result<(), FlowyError> { let database_layout = match new.layout { ViewLayout::Document | ViewLayout::Chat => { - return FutureResult::new(async { - Err(FlowyError::internal().with_context("Can't handle document layout type")) - }); + return Err(FlowyError::internal().with_context("Can't handle document layout type")); }, ViewLayout::Grid => DatabaseLayoutPB::Grid, ViewLayout::Board => DatabaseLayoutPB::Board, ViewLayout::Calendar => DatabaseLayoutPB::Calendar, }; - let database_manager = self.0.clone(); - let view_id = new.id.clone(); if old.layout != new.layout { - FutureResult::new(async move { - database_manager - .update_database_layout(&view_id, database_layout) - .await?; - Ok(()) - }) + self + .0 + .update_database_layout(&new.id, database_layout) + .await?; + Ok(()) } else { - FutureResult::new(async move { Ok(()) }) + Ok(()) } } } @@ -599,78 +522,61 @@ impl CreateDatabaseExtParams { } struct ChatFolderOperation(Arc); + +#[async_trait] impl FolderOperationHandler for ChatFolderOperation { - fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - manager.open_chat(&view_id).await?; - Ok(()) - }) + async fn open_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.open_chat(view_id).await } - fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - manager.close_chat(&view_id).await?; - Ok(()) - }) + async fn close_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.close_chat(view_id).await } - fn delete_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - manager.delete_chat(&view_id).await?; - Ok(()) - }) + async fn delete_view(&self, view_id: &str) -> Result<(), FlowyError> { + self.0.delete_chat(view_id).await } - fn duplicate_view(&self, _view_id: &str) -> FutureResult { - FutureResult::new(async move { Err(FlowyError::not_support()) }) + async fn duplicate_view(&self, _view_id: &str) -> Result { + Err(FlowyError::not_support()) } - fn create_view_with_view_data( + async fn create_view_with_view_data( &self, _user_id: i64, _params: CreateViewParams, - ) -> FutureResult, FlowyError> { - FutureResult::new(async move { Err(FlowyError::not_support()) }) + ) -> Result, FlowyError> { + Err(FlowyError::not_support()) } - fn create_built_in_view( + async fn create_built_in_view( &self, user_id: i64, view_id: &str, _name: &str, _layout: ViewLayout, - ) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); - let view_id = view_id.to_string(); - FutureResult::new(async move { - manager.create_chat(&user_id, &view_id).await?; - Ok(()) - }) + ) -> Result<(), FlowyError> { + self.0.create_chat(&user_id, view_id).await?; + Ok(()) } - fn import_from_bytes( + async fn import_from_bytes( &self, _uid: i64, _view_id: &str, _name: &str, _import_type: ImportType, _bytes: Vec, - ) -> FutureResult { - FutureResult::new(async move { Err(FlowyError::not_support()) }) + ) -> Result { + Err(FlowyError::not_support()) } - fn import_from_file_path( + async fn import_from_file_path( &self, _view_id: &str, _name: &str, _path: String, - ) -> FutureResult<(), FlowyError> { - FutureResult::new(async move { Err(FlowyError::not_support()) }) + ) -> Result<(), FlowyError> { + Err(FlowyError::not_support()) } } diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index f184b5a020..01ef68636f 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -595,22 +595,17 @@ impl CollabCloudPluginProvider for ServerProvider { #[async_trait] impl ChatCloudService for ServerProvider { - fn create_chat( + async fn create_chat( &self, uid: &i64, workspace_id: &str, chat_id: &str, - ) -> FutureResult<(), FlowyError> { - let workspace_id = workspace_id.to_string(); + ) -> Result<(), FlowyError> { let server = self.get_server(); - let chat_id = chat_id.to_string(); - let uid = *uid; - FutureResult::new(async move { - server? - .chat_service() - .create_chat(&uid, &workspace_id, &chat_id) - .await - }) + server? + .chat_service() + .create_chat(uid, workspace_id, chat_id) + .await } async fn create_question( diff --git a/frontend/rust-lib/flowy-core/src/integrate/user.rs b/frontend/rust-lib/flowy-core/src/integrate/user.rs index 5cc5f787a4..f9bfb46280 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/user.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/user.rs @@ -15,7 +15,7 @@ use flowy_storage::manager::StorageManager; use flowy_user::event_map::UserStatusCallback; use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider}; use flowy_user_pub::entities::{Authenticator, UserProfile, UserWorkspace}; -use lib_infra::future::{to_fut, Fut}; +use lib_infra::async_trait::async_trait; use crate::integrate::server::{Server, ServerProvider}; @@ -29,21 +29,16 @@ pub(crate) struct UserStatusCallbackImpl { pub(crate) ai_manager: Arc, } +#[async_trait] impl UserStatusCallback for UserStatusCallbackImpl { - fn did_init( + async fn did_init( &self, user_id: i64, user_authenticator: &Authenticator, cloud_config: &Option, user_workspace: &UserWorkspace, _device_id: &str, - ) -> Fut> { - let user_id = user_id.to_owned(); - let user_workspace = user_workspace.clone(); - let folder_manager = self.folder_manager.clone(); - let database_manager = self.database_manager.clone(); - let document_manager = self.document_manager.clone(); - + ) -> FlowyResult<()> { self .server_provider .set_user_authenticator(user_authenticator); @@ -59,159 +54,142 @@ impl UserStatusCallback for UserStatusCallbackImpl { } } - to_fut(async move { - folder_manager - .initialize( - user_id, - &user_workspace.id, - FolderInitDataSource::LocalDisk { - create_if_not_exist: false, - }, - ) - .await?; - database_manager.initialize(user_id).await?; - document_manager.initialize(user_id).await?; - Ok(()) - }) + self + .folder_manager + .initialize( + user_id, + &user_workspace.id, + FolderInitDataSource::LocalDisk { + create_if_not_exist: false, + }, + ) + .await?; + self.database_manager.initialize(user_id).await?; + self.document_manager.initialize(user_id).await?; + Ok(()) } - fn did_sign_in( + async fn did_sign_in( &self, user_id: i64, user_workspace: &UserWorkspace, device_id: &str, - ) -> Fut> { - let device_id = device_id.to_owned(); - let user_id = user_id.to_owned(); - let user_workspace = user_workspace.clone(); - let folder_manager = self.folder_manager.clone(); - let database_manager = self.database_manager.clone(); - let document_manager = self.document_manager.clone(); + ) -> FlowyResult<()> { + event!( + tracing::Level::TRACE, + "Notify did sign in: latest_workspace: {:?}, device_id: {}", + user_workspace, + device_id + ); - to_fut(async move { - event!( - tracing::Level::TRACE, - "Notify did sign in: latest_workspace: {:?}, device_id: {}", - user_workspace, - device_id - ); - - folder_manager.initialize_with_workspace_id(user_id).await?; - database_manager.initialize(user_id).await?; - document_manager.initialize(user_id).await?; - Ok(()) - }) + self + .folder_manager + .initialize_with_workspace_id(user_id) + .await?; + self.database_manager.initialize(user_id).await?; + self.document_manager.initialize(user_id).await?; + Ok(()) } - fn did_sign_up( + async fn did_sign_up( &self, is_new_user: bool, user_profile: &UserProfile, user_workspace: &UserWorkspace, device_id: &str, - ) -> Fut> { - let device_id = device_id.to_owned(); - let user_profile = user_profile.clone(); - let folder_manager = self.folder_manager.clone(); - let database_manager = self.database_manager.clone(); - let user_workspace = user_workspace.clone(); - let document_manager = self.document_manager.clone(); + ) -> FlowyResult<()> { self .server_provider .set_user_authenticator(&user_profile.authenticator); let server_type = self.server_provider.get_server_type(); - to_fut(async move { - event!( - tracing::Level::TRACE, - "Notify did sign up: is new: {} user_workspace: {:?}, device_id: {}", - is_new_user, - user_workspace, - device_id - ); + event!( + tracing::Level::TRACE, + "Notify did sign up: is new: {} user_workspace: {:?}, device_id: {}", + is_new_user, + user_workspace, + device_id + ); - // In the current implementation, when a user signs up for AppFlowy Cloud, a default workspace - // is automatically created for them. However, for users who sign up through Supabase, the creation - // of the default workspace relies on the client-side operation. This means that the process - // for initializing a default workspace differs depending on the sign-up method used. - let data_source = match folder_manager - .cloud_service - .get_folder_doc_state( - &user_workspace.id, - user_profile.uid, - CollabType::Folder, - &user_workspace.id, - ) - .await - { - Ok(doc_state) => match server_type { - Server::Local => FolderInitDataSource::LocalDisk { - create_if_not_exist: true, - }, - Server::AppFlowyCloud => FolderInitDataSource::Cloud(doc_state), - Server::Supabase => { - if is_new_user { - FolderInitDataSource::LocalDisk { - create_if_not_exist: true, - } - } else { - FolderInitDataSource::Cloud(doc_state) + // In the current implementation, when a user signs up for AppFlowy Cloud, a default workspace + // is automatically created for them. However, for users who sign up through Supabase, the creation + // of the default workspace relies on the client-side operation. This means that the process + // for initializing a default workspace differs depending on the sign-up method used. + let data_source = match self + .folder_manager + .cloud_service + .get_folder_doc_state( + &user_workspace.id, + user_profile.uid, + CollabType::Folder, + &user_workspace.id, + ) + .await + { + Ok(doc_state) => match server_type { + Server::Local => FolderInitDataSource::LocalDisk { + create_if_not_exist: true, + }, + Server::AppFlowyCloud => FolderInitDataSource::Cloud(doc_state), + Server::Supabase => { + if is_new_user { + FolderInitDataSource::LocalDisk { + create_if_not_exist: true, } - }, + } else { + FolderInitDataSource::Cloud(doc_state) + } }, - Err(err) => match server_type { - Server::Local => FolderInitDataSource::LocalDisk { - create_if_not_exist: true, - }, - Server::AppFlowyCloud | Server::Supabase => { - return Err(FlowyError::from(err)); - }, + }, + Err(err) => match server_type { + Server::Local => FolderInitDataSource::LocalDisk { + create_if_not_exist: true, }, - }; + Server::AppFlowyCloud | Server::Supabase => { + return Err(FlowyError::from(err)); + }, + }, + }; - folder_manager - .initialize_with_new_user( - user_profile.uid, - &user_profile.token, - is_new_user, - data_source, - &user_workspace.id, - ) - .await - .context("FolderManager error")?; + self + .folder_manager + .initialize_with_new_user( + user_profile.uid, + &user_profile.token, + is_new_user, + data_source, + &user_workspace.id, + ) + .await + .context("FolderManager error")?; - database_manager - .initialize_with_new_user(user_profile.uid) - .await - .context("DatabaseManager error")?; + self + .database_manager + .initialize_with_new_user(user_profile.uid) + .await + .context("DatabaseManager error")?; - document_manager - .initialize_with_new_user(user_profile.uid) - .await - .context("DocumentManager error")?; - Ok(()) - }) + self + .document_manager + .initialize_with_new_user(user_profile.uid) + .await + .context("DocumentManager error")?; + Ok(()) } - fn did_expired(&self, _token: &str, user_id: i64) -> Fut> { - let folder_manager = self.folder_manager.clone(); - to_fut(async move { - folder_manager.clear(user_id).await; - Ok(()) - }) + async fn did_expired(&self, _token: &str, user_id: i64) -> FlowyResult<()> { + self.folder_manager.clear(user_id).await; + Ok(()) } - fn open_workspace(&self, user_id: i64, _user_workspace: &UserWorkspace) -> Fut> { - let folder_manager = self.folder_manager.clone(); - let database_manager = self.database_manager.clone(); - let document_manager = self.document_manager.clone(); - - to_fut(async move { - folder_manager.initialize_with_workspace_id(user_id).await?; - database_manager.initialize(user_id).await?; - document_manager.initialize(user_id).await?; - Ok(()) - }) + async fn open_workspace(&self, user_id: i64, _user_workspace: &UserWorkspace) -> FlowyResult<()> { + self + .folder_manager + .initialize_with_workspace_id(user_id) + .await?; + self.database_manager.initialize(user_id).await?; + self.document_manager.initialize(user_id).await?; + Ok(()) } fn did_update_network(&self, reachable: bool) { diff --git a/frontend/rust-lib/flowy-folder/src/view_operation.rs b/frontend/rust-lib/flowy-folder/src/view_operation.rs index 0f8df99e08..fd5f90d206 100644 --- a/frontend/rust-lib/flowy-folder/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder/src/view_operation.rs @@ -1,16 +1,15 @@ -use std::collections::HashMap; -use std::sync::Arc; - +use async_trait::async_trait; use bytes::Bytes; use collab::entity::EncodedCollab; pub use collab_folder::View; use collab_folder::ViewLayout; +use std::collections::HashMap; +use std::sync::Arc; use tokio::sync::RwLock; use flowy_error::FlowyError; use flowy_folder_pub::folder_builder::NestedViewBuilder; -use lib_infra::future::FutureResult; use lib_infra::util::timestamp; use crate::entities::{CreateViewParams, ViewLayoutPB}; @@ -42,36 +41,37 @@ pub struct DatabaseEncodedCollab { /// view layout. Each [ViewLayout] will have a handler. So when creating a new /// view, the [ViewLayout] will be used to get the handler. /// +#[async_trait] pub trait FolderOperationHandler { /// Create the view for the workspace of new user. /// Only called once when the user is created. - fn create_workspace_view( + async fn create_workspace_view( &self, _uid: i64, _workspace_view_builder: Arc>, - ) -> FutureResult<(), FlowyError> { - FutureResult::new(async { Ok(()) }) + ) -> Result<(), FlowyError> { + Ok(()) } - fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError>; + async fn open_view(&self, view_id: &str) -> Result<(), FlowyError>; /// Closes the view and releases the resources that this view has in /// the backend - fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError>; + async fn close_view(&self, view_id: &str) -> Result<(), FlowyError>; /// Called when the view is deleted. /// This will called after the view is deleted from the trash. - fn delete_view(&self, view_id: &str) -> FutureResult<(), FlowyError>; + async fn delete_view(&self, view_id: &str) -> Result<(), FlowyError>; /// Returns the [ViewData] that can be used to create the same view. - fn duplicate_view(&self, view_id: &str) -> FutureResult; + async fn duplicate_view(&self, view_id: &str) -> Result; /// get the encoded collab data from the disk. - fn get_encoded_collab_v1_from_disk( + async fn get_encoded_collab_v1_from_disk( &self, _user: Arc, _view_id: &str, - ) -> FutureResult { - FutureResult::new(async move { Err(FlowyError::not_support()) }) + ) -> Result { + Err(FlowyError::not_support()) } /// Create a view with the data. @@ -92,46 +92,46 @@ pub trait FolderOperationHandler { /// /// The return value is the [Option] that can be used to create the view. /// It can be used in syncing the view data to cloud. - fn create_view_with_view_data( + async fn create_view_with_view_data( &self, user_id: i64, params: CreateViewParams, - ) -> FutureResult, FlowyError>; + ) -> Result, FlowyError>; /// Create a view with the pre-defined data. /// For example, the initial data of the grid/calendar/kanban board when /// you create a new view. - fn create_built_in_view( + async fn create_built_in_view( &self, user_id: i64, view_id: &str, name: &str, layout: ViewLayout, - ) -> FutureResult<(), FlowyError>; + ) -> Result<(), FlowyError>; /// Create a view by importing data /// /// The return value - fn import_from_bytes( + async fn import_from_bytes( &self, uid: i64, view_id: &str, name: &str, import_type: ImportType, bytes: Vec, - ) -> FutureResult; + ) -> Result; /// Create a view by importing data from a file - fn import_from_file_path( + async fn import_from_file_path( &self, view_id: &str, name: &str, path: String, - ) -> FutureResult<(), FlowyError>; + ) -> Result<(), FlowyError>; /// Called when the view is updated. The handler is the `old` registered handler. - fn did_update_view(&self, _old: &View, _new: &View) -> FutureResult<(), FlowyError> { - FutureResult::new(async move { Ok(()) }) + async fn did_update_view(&self, _old: &View, _new: &View) -> Result<(), FlowyError> { + Ok(()) } } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs index 2e8e1a8eab..67df702860 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs @@ -13,7 +13,6 @@ use flowy_ai_pub::cloud::{ use flowy_error::FlowyError; use futures_util::{StreamExt, TryStreamExt}; use lib_infra::async_trait::async_trait; -use lib_infra::future::FutureResult; use lib_infra::util::{get_operating_system, OperatingSystem}; use serde_json::{json, Value}; use std::collections::HashMap; @@ -28,29 +27,25 @@ impl ChatCloudService for AFCloudChatCloudServiceImpl where T: AFServer, { - fn create_chat( + async fn create_chat( &self, _uid: &i64, workspace_id: &str, chat_id: &str, - ) -> FutureResult<(), FlowyError> { - let workspace_id = workspace_id.to_string(); + ) -> Result<(), FlowyError> { let chat_id = chat_id.to_string(); let try_get_client = self.inner.try_get_client(); + let params = CreateChatParams { + chat_id, + name: "".to_string(), + rag_ids: vec![], + }; + try_get_client? + .create_chat(workspace_id, params) + .await + .map_err(FlowyError::from)?; - FutureResult::new(async move { - let params = CreateChatParams { - chat_id, - name: "".to_string(), - rag_ids: vec![], - }; - try_get_client? - .create_chat(&workspace_id, params) - .await - .map_err(FlowyError::from)?; - - Ok(()) - }) + Ok(()) } async fn create_question( diff --git a/frontend/rust-lib/flowy-server/src/default_impl.rs b/frontend/rust-lib/flowy-server/src/default_impl.rs index 0e22a6313f..ea41746424 100644 --- a/frontend/rust-lib/flowy-server/src/default_impl.rs +++ b/frontend/rust-lib/flowy-server/src/default_impl.rs @@ -5,7 +5,6 @@ use flowy_ai_pub::cloud::{ }; use flowy_error::FlowyError; use lib_infra::async_trait::async_trait; -use lib_infra::future::FutureResult; use serde_json::Value; use std::collections::HashMap; use std::path::Path; @@ -14,15 +13,13 @@ pub(crate) struct DefaultChatCloudServiceImpl; #[async_trait] impl ChatCloudService for DefaultChatCloudServiceImpl { - fn create_chat( + async fn create_chat( &self, _uid: &i64, _workspace_id: &str, _chat_id: &str, - ) -> FutureResult<(), FlowyError> { - FutureResult::new(async move { - Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) - }) + ) -> Result<(), FlowyError> { + Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) } async fn create_question( diff --git a/frontend/rust-lib/flowy-user/src/event_map.rs b/frontend/rust-lib/flowy-user/src/event_map.rs index 6a9a1403d5..6e03928c6e 100644 --- a/frontend/rust-lib/flowy-user/src/event_map.rs +++ b/frontend/rust-lib/flowy-user/src/event_map.rs @@ -7,7 +7,7 @@ use flowy_error::FlowyResult; use flowy_user_pub::cloud::UserCloudConfig; use flowy_user_pub::entities::*; use lib_dispatch::prelude::*; -use lib_infra::future::{to_fut, Fut}; +use lib_infra::async_trait::async_trait; use crate::event_handler::*; use crate::user_manager::UserManager; @@ -276,38 +276,53 @@ pub enum UserEvent { NotifyDidSwitchPlan = 63, } +#[async_trait] pub trait UserStatusCallback: Send + Sync + 'static { /// When the [Authenticator] changed, this method will be called. Currently, the auth type /// will be changed when the user sign in or sign up. fn authenticator_did_changed(&self, _authenticator: Authenticator) {} /// This will be called after the application launches if the user is already signed in. /// If the user is not signed in, this method will not be called - fn did_init( + async fn did_init( &self, - user_id: i64, - user_authenticator: &Authenticator, - cloud_config: &Option, - user_workspace: &UserWorkspace, - device_id: &str, - ) -> Fut>; + _user_id: i64, + _user_authenticator: &Authenticator, + _cloud_config: &Option, + _user_workspace: &UserWorkspace, + _device_id: &str, + ) -> FlowyResult<()> { + Ok(()) + } /// Will be called after the user signed in. - fn did_sign_in( + async fn did_sign_in( &self, - user_id: i64, - user_workspace: &UserWorkspace, - device_id: &str, - ) -> Fut>; + _user_id: i64, + _user_workspace: &UserWorkspace, + _device_id: &str, + ) -> FlowyResult<()> { + Ok(()) + } /// Will be called after the user signed up. - fn did_sign_up( + async fn did_sign_up( &self, - is_new_user: bool, - user_profile: &UserProfile, - user_workspace: &UserWorkspace, - device_id: &str, - ) -> Fut>; + _is_new_user: bool, + _user_profile: &UserProfile, + _user_workspace: &UserWorkspace, + _device_id: &str, + ) -> FlowyResult<()> { + Ok(()) + } - fn did_expired(&self, token: &str, user_id: i64) -> Fut>; - fn open_workspace(&self, user_id: i64, user_workspace: &UserWorkspace) -> Fut>; + async fn did_expired(&self, _token: &str, _user_id: i64) -> FlowyResult<()> { + Ok(()) + } + async fn open_workspace( + &self, + _user_id: i64, + _user_workspace: &UserWorkspace, + ) -> FlowyResult<()> { + Ok(()) + } fn did_update_network(&self, _reachable: bool) {} fn did_update_plans(&self, _plans: Vec) {} fn did_update_storage_limitation(&self, _can_write: bool) {} @@ -315,42 +330,4 @@ pub trait UserStatusCallback: Send + Sync + 'static { /// Acts as a placeholder [UserStatusCallback] for the user session, but does not perform any function pub(crate) struct DefaultUserStatusCallback; -impl UserStatusCallback for DefaultUserStatusCallback { - fn did_init( - &self, - _user_id: i64, - _authenticator: &Authenticator, - _cloud_config: &Option, - _user_workspace: &UserWorkspace, - _device_id: &str, - ) -> Fut> { - to_fut(async { Ok(()) }) - } - - fn did_sign_in( - &self, - _user_id: i64, - _user_workspace: &UserWorkspace, - _device_id: &str, - ) -> Fut> { - to_fut(async { Ok(()) }) - } - - fn did_sign_up( - &self, - _is_new_user: bool, - _user_profile: &UserProfile, - _user_workspace: &UserWorkspace, - _device_id: &str, - ) -> Fut> { - to_fut(async { Ok(()) }) - } - - fn did_expired(&self, _token: &str, _user_id: i64) -> Fut> { - to_fut(async { Ok(()) }) - } - - fn open_workspace(&self, _user_id: i64, _user_workspace: &UserWorkspace) -> Fut> { - to_fut(async { Ok(()) }) - } -} +impl UserStatusCallback for DefaultUserStatusCallback {} diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs b/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs index 5604024be3..47d7167fb4 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs @@ -33,7 +33,7 @@ where pub fn load_collab_by_object_id<'a, R>( uid: i64, collab_read_txn: &R, - object_id: &String, + object_id: &str, ) -> Result where R: CollabKVAction<'a>, diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index 6b448ba6f8..97cc6747f2 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -581,7 +581,6 @@ impl UserManager { Ok(UseAISettingPB::from(settings)) } - #[instrument(level = "debug", skip(self), err)] pub async fn get_workspace_member_info(&self, uid: i64) -> FlowyResult { let workspace_id = self.get_session()?.user_workspace.id.clone(); let db = self.authenticate_user.get_sqlite_connection(uid)?;