From a50c9402829fddfc9ab53ba9cded6fd6305943ef Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Mon, 5 Jun 2023 09:42:11 +0800 Subject: [PATCH] feat: delete the view from the db when the view is deleted (#2703) --- frontend/appflowy_tauri/src-tauri/Cargo.toml | 12 ++-- frontend/rust-lib/Cargo.lock | 20 +++---- frontend/rust-lib/Cargo.toml | 10 ++-- .../src/deps_resolve/folder2_deps.rs | 28 +++++++++- .../rust-lib/flowy-database2/src/manager.rs | 6 ++ .../flowy-database2/src/notification.rs | 5 ++ .../src/services/cell/cell_operation.rs | 2 +- .../src/services/database/database_editor.rs | 10 +++- .../src/services/database_view/view_group.rs | 4 +- .../flowy-document2/src/event_handler.rs | 2 +- .../rust-lib/flowy-document2/src/manager.rs | 16 +++++- .../tests/document/document_test.rs | 19 ++++--- .../flowy-folder2/src/event_handler.rs | 11 ++-- .../rust-lib/flowy-folder2/src/manager.rs | 55 ++++++++++--------- .../flowy-folder2/src/view_operation.rs | 22 +++++--- 15 files changed, 143 insertions(+), 79 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 117e8616cb..36be9d1817 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -34,12 +34,12 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } #collab = { path = "../../AppFlowy-Collab/collab" } #collab-folder = { path = "../../AppFlowy-Collab/collab-folder" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 12b04fd0ba..d73f0f64b0 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -85,7 +85,7 @@ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" [[package]] name = "appflowy-integrate" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "anyhow", "collab", @@ -887,7 +887,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "anyhow", "bytes", @@ -905,7 +905,7 @@ dependencies = [ [[package]] name = "collab-client-ws" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "bytes", "collab-sync", @@ -923,7 +923,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "anyhow", "async-trait", @@ -949,7 +949,7 @@ dependencies = [ [[package]] name = "collab-derive" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "proc-macro2", "quote", @@ -961,7 +961,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "anyhow", "collab", @@ -978,7 +978,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "anyhow", "collab", @@ -997,7 +997,7 @@ dependencies = [ [[package]] name = "collab-persistence" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "bincode", "chrono", @@ -1017,7 +1017,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "anyhow", "async-trait", @@ -1047,7 +1047,7 @@ dependencies = [ [[package]] name = "collab-sync" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab" dependencies = [ "bytes", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 7814e0d3fd..ce6e8cb048 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -33,11 +33,11 @@ opt-level = 3 incremental = false [patch.crates-io] -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } -appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "13b178" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } +appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cbc2e0" } #collab = { path = "../AppFlowy-Collab/collab" } #collab-folder = { path = "../AppFlowy-Collab/collab-folder" } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder2_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder2_deps.rs index c8eea5077b..7591ff25ec 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder2_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder2_deps.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use appflowy_integrate::collab_builder::AppFlowyCollabBuilder; use appflowy_integrate::RocksCollabDB; use bytes::Bytes; +use tokio::sync::RwLock; use flowy_database2::entities::DatabaseLayoutPB; use flowy_database2::services::share::csv::CSVFormat; @@ -24,7 +25,6 @@ use flowy_folder2::ViewLayout; use flowy_user::services::UserSession; use lib_dispatch::prelude::ToBytes; use lib_infra::future::FutureResult; -use tokio::sync::RwLock; pub struct Folder2DepsResolver(); impl Folder2DepsResolver { @@ -121,7 +121,19 @@ impl FolderOperationHandler for DocumentFolderOperation { let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - manager.close_document(view_id)?; + manager.close_document(&view_id)?; + 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) { + Ok(_) => tracing::trace!("Delete document: {}", view_id), + Err(e) => tracing::error!("Failed to delete document: {}", e), + } Ok(()) }) } @@ -210,6 +222,18 @@ impl FolderOperationHandler for DatabaseFolderOperation { }) } + 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!("Failed to delete database: {}", e), + } + Ok(()) + }) + } + fn duplicate_view(&self, view_id: &str) -> FutureResult { let database_manager = self.0.clone(); let view_id = view_id.to_owned(); diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 4648ab2652..c8a28dbe91 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -132,6 +132,12 @@ impl DatabaseManager2 { Ok(()) } + pub async fn delete_database_view(&self, view_id: &str) -> FlowyResult<()> { + let database = self.get_database_with_view_id(view_id).await?; + let _ = database.delete_database_view(view_id).await?; + Ok(()) + } + pub async fn duplicate_database(&self, view_id: &str) -> FlowyResult> { let database_data = self.with_user_database(Err(FlowyError::internal()), |database| { let data = database.get_database_duplicated_data(view_id)?; diff --git a/frontend/rust-lib/flowy-database2/src/notification.rs b/frontend/rust-lib/flowy-database2/src/notification.rs index 72e8287982..0f0ffad160 100644 --- a/frontend/rust-lib/flowy-database2/src/notification.rs +++ b/frontend/rust-lib/flowy-database2/src/notification.rs @@ -1,5 +1,6 @@ use flowy_derive::ProtoBuf_Enum; use flowy_notification::NotificationBuilder; + const OBSERVABLE_CATEGORY: &str = "Grid"; #[derive(ProtoBuf_Enum, Debug)] @@ -37,6 +38,10 @@ pub enum DatabaseNotification { DidSetNewLayoutField = 81, // Trigger when the layout of the database is changed DidUpdateDatabaseLayout = 82, + // Trigger when the database view is deleted + DidDeleteDatabaseView = 83, + // Trigger when the database view is moved to trash + DidMoveDatabaseViewToTrash = 84, } impl std::default::Default for DatabaseNotification { diff --git a/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs b/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs index 58b52b6a33..5403d1fca6 100644 --- a/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs +++ b/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs @@ -312,7 +312,7 @@ impl<'a> CellBuilder<'a> { .collect::>(); let mut cells = Cells::new(); - for (field_id, cell_str) in cell_by_field_id.clone() { + for (field_id, cell_str) in cell_by_field_id { if let Some(field) = field_maps.get(&field_id) { let field_type = FieldType::from(field.field_type); match field_type { diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 9f1c5085af..7ebbd46520 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -125,6 +125,14 @@ impl DatabaseEditor { Ok(()) } + /// Returns the delete view ids. + /// If the view is inline view, all the reference views will be deleted. So the return value + /// will be the reference view ids and the inline view id. Otherwise, the return value will + /// be the view id. + pub async fn delete_database_view(&self, view_id: &str) -> FlowyResult> { + Ok(self.database.lock().delete_view(view_id)) + } + pub async fn update_group_setting( &self, view_id: &str, @@ -942,7 +950,7 @@ impl DatabaseEditor { let view = database_view .get_view() .await - .ok_or_else(|| FlowyError::record_not_found())?; + .ok_or_else(FlowyError::record_not_found)?; let rows = database_view.v_get_rows().await; let (database_id, fields) = { let database = self.database.lock(); diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs index 128635e9dd..b79ea3eb3e 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs @@ -108,7 +108,7 @@ pub(crate) async fn get_cell_for_row( let cell_data = match &row_cell.cell { None => None, - Some(cell) => handler.get_cell_data(&cell, &field_type, &field).ok(), + Some(cell) => handler.get_cell_data(cell, &field_type, &field).ok(), }; Some(RowSingleCellData { row_id: row_cell.row_id.clone(), @@ -133,7 +133,7 @@ pub(crate) async fn get_cells_for_field( .map(|row_cell| { let cell_data = match &row_cell.cell { None => None, - Some(cell) => handler.get_cell_data(&cell, &field_type, &field).ok(), + Some(cell) => handler.get_cell_data(cell, &field_type, &field).ok(), }; RowSingleCellData { row_id: row_cell.row_id.clone(), diff --git a/frontend/rust-lib/flowy-document2/src/event_handler.rs b/frontend/rust-lib/flowy-document2/src/event_handler.rs index 7dea2c7bf5..909f398e91 100644 --- a/frontend/rust-lib/flowy-document2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-document2/src/event_handler.rs @@ -51,7 +51,7 @@ pub(crate) async fn close_document_handler( manager: AFPluginState>, ) -> FlowyResult<()> { let context = data.into_inner(); - manager.close_document(context.document_id)?; + manager.close_document(&context.document_id)?; Ok(()) } diff --git a/frontend/rust-lib/flowy-document2/src/manager.rs b/frontend/rust-lib/flowy-document2/src/manager.rs index 220c131d49..c4b5958722 100644 --- a/frontend/rust-lib/flowy-document2/src/manager.rs +++ b/frontend/rust-lib/flowy-document2/src/manager.rs @@ -3,6 +3,7 @@ use std::{collections::HashMap, sync::Arc}; use appflowy_integrate::collab_builder::AppFlowyCollabBuilder; use appflowy_integrate::RocksCollabDB; use collab_document::blocks::DocumentData; +use collab_document::YrsDocAction; use parking_lot::RwLock; use flowy_error::{FlowyError, FlowyResult}; @@ -96,8 +97,19 @@ impl DocumentManager { Ok(document) } - pub fn close_document(&self, doc_id: String) -> FlowyResult<()> { - self.documents.write().remove(&doc_id); + pub fn close_document(&self, doc_id: &str) -> FlowyResult<()> { + self.documents.write().remove(doc_id); + Ok(()) + } + + pub fn delete_document(&self, doc_id: &str) -> FlowyResult<()> { + let uid = self.user.user_id()?; + let db = self.user.collab_db()?; + let _ = db.with_write_txn(|txn| { + txn.delete_doc(uid, &doc_id)?; + Ok(()) + }); + self.documents.write().remove(doc_id); Ok(()) } } diff --git a/frontend/rust-lib/flowy-document2/tests/document/document_test.rs b/frontend/rust-lib/flowy-document2/tests/document/document_test.rs index c2392ac536..3550110185 100644 --- a/frontend/rust-lib/flowy-document2/tests/document/document_test.rs +++ b/frontend/rust-lib/flowy-document2/tests/document/document_test.rs @@ -1,14 +1,15 @@ use std::{collections::HashMap, sync::Arc, vec}; use collab_document::blocks::{Block, BlockAction, BlockActionPayload, BlockActionType}; -use flowy_document2::document_block_keys::PARAGRAPH_BLOCK_TYPE; use nanoid::nanoid; use serde_json::{json, to_value, Value}; -use crate::document::util::default_collab_builder; +use flowy_document2::document_block_keys::PARAGRAPH_BLOCK_TYPE; use flowy_document2::document_data::default_document_data; use flowy_document2::manager::DocumentManager; +use crate::document::util::default_collab_builder; + use super::util::FakeUser; #[test] @@ -33,7 +34,7 @@ fn restore_document() { .get_document() .unwrap(); // close a document - _ = manager.close_document(doc_id.clone()); + _ = manager.close_document(&doc_id); assert_eq!(data_b, data); // restore @@ -46,7 +47,7 @@ fn restore_document() { .get_document() .unwrap(); // close a document - _ = manager.close_document(doc_id); + _ = manager.close_document(&doc_id); assert_eq!(data_b, data); } @@ -87,7 +88,7 @@ fn document_apply_insert_action() { document.lock().apply_action(vec![insert_text_action]); let data_a = document.lock().get_document().unwrap(); // close the original document - _ = manager.close_document(doc_id.clone()); + _ = manager.close_document(&doc_id); // re-open the document let data_b = manager @@ -97,7 +98,7 @@ fn document_apply_insert_action() { .get_document() .unwrap(); // close a document - _ = manager.close_document(doc_id); + _ = manager.close_document(&doc_id); assert_eq!(data_b, data_a); } @@ -135,7 +136,7 @@ fn document_apply_update_page_action() { tracing::trace!("{:?}", &actions); document.lock().apply_action(actions); let page_block_old = document.lock().get_block(&data.page_id).unwrap(); - _ = manager.close_document(doc_id.clone()); + _ = manager.close_document(&doc_id); // re-open the document let document = manager.open_document(doc_id).unwrap(); @@ -203,12 +204,12 @@ fn document_apply_update_action() { }; document.lock().apply_action(vec![update_text_action]); // close the original document - _ = manager.close_document(doc_id.clone()); + _ = manager.close_document(&doc_id); // re-open the document let document = manager.open_document(doc_id.clone()).unwrap(); let block = document.lock().get_block(&text_block_id).unwrap(); assert_eq!(block.data, updated_text_block_data); // close a document - _ = manager.close_document(doc_id); + _ = manager.close_document(&doc_id); } diff --git a/frontend/rust-lib/flowy-folder2/src/event_handler.rs b/frontend/rust-lib/flowy-folder2/src/event_handler.rs index eee1e5205c..2a0d83dee2 100644 --- a/frontend/rust-lib/flowy-folder2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder2/src/event_handler.rs @@ -1,3 +1,8 @@ +use std::sync::Arc; + +use flowy_error::FlowyError; +use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; + use crate::entities::{ view_pb_without_child_views, CreateViewParams, CreateViewPayloadPB, CreateWorkspaceParams, CreateWorkspacePayloadPB, ImportPB, MoveFolderItemPayloadPB, MoveViewParams, RepeatedTrashIdPB, @@ -6,11 +11,7 @@ use crate::entities::{ WorkspaceSettingPB, }; use crate::manager::Folder2Manager; - use crate::share::ImportParams; -use flowy_error::FlowyError; -use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; -use std::sync::Arc; #[tracing::instrument(level = "debug", skip(data, folder), err)] pub(crate) async fn create_workspace_handler( @@ -187,7 +188,7 @@ pub(crate) async fn delete_trash_handler( ) -> Result<(), FlowyError> { let trash_ids = identifiers.into_inner().items; for trash_id in trash_ids { - folder.delete_trash(&trash_id.id).await; + let _ = folder.delete_trash(&trash_id.id).await; } Ok(()) } diff --git a/frontend/rust-lib/flowy-folder2/src/manager.rs b/frontend/rust-lib/flowy-folder2/src/manager.rs index 58a5e56075..4c204e4c88 100644 --- a/frontend/rust-lib/flowy-folder2/src/manager.rs +++ b/frontend/rust-lib/flowy-folder2/src/manager.rs @@ -1,24 +1,22 @@ use std::collections::{HashMap, HashSet}; - use std::ops::Deref; use std::sync::{Arc, Weak}; use appflowy_integrate::collab_builder::AppFlowyCollabBuilder; use collab::core::collab_state::CollabState; - use collab_folder::core::{ Folder, FolderContext, TrashChange, TrashChangeReceiver, TrashInfo, TrashRecord, View, ViewChange, ViewChangeReceiver, ViewLayout, Workspace, }; use parking_lot::Mutex; -use tracing::{event, Level}; - -use crate::deps::{FolderCloudService, FolderUser}; -use flowy_error::{ErrorCode, FlowyError, FlowyResult}; -use lib_infra::util::timestamp; use tokio_stream::wrappers::WatchStream; use tokio_stream::StreamExt; +use tracing::{event, Level}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; +use lib_infra::util::timestamp; + +use crate::deps::{FolderCloudService, FolderUser}; use crate::entities::{ view_pb_with_child_views, CreateViewParams, CreateWorkspaceParams, RepeatedTrashPB, RepeatedViewPB, RepeatedWorkspacePB, UpdateViewParams, ViewPB, @@ -302,12 +300,6 @@ impl Folder2Manager { } } - #[tracing::instrument(level = "debug", skip(self, view_id), err)] - pub async fn delete_view(&self, view_id: &str) -> FlowyResult<()> { - self.with_folder((), |folder| folder.views.delete_views(vec![view_id])); - Ok(()) - } - /// Move the view to trash. If the view is the current view, then set the current view to empty. /// When the view is moved to trash, all the child views will be moved to trash as well. #[tracing::instrument(level = "debug", skip(self), err)] @@ -453,27 +445,36 @@ impl Folder2Manager { }); } - #[tracing::instrument(level = "trace", skip(self))] - pub(crate) async fn delete_trash(&self, trash_id: &str) { - self.with_folder((), |folder| { - folder.trash.delete_trash(vec![trash_id]); - folder.views.delete_views(vec![trash_id]); - }) - } - + /// Delete all the trash permanently. #[tracing::instrument(level = "trace", skip(self))] pub(crate) async fn delete_all_trash(&self) { - self.with_folder((), |folder| { - let trash = folder.trash.get_all_trash(); - folder.trash.clear(); - folder.views.delete_views(trash); - }); - + let deleted_trash = self.with_folder(vec![], |folder| folder.trash.get_all_trash()); + for trash in deleted_trash { + let _ = self.delete_trash(&trash.id).await; + } send_notification("trash", FolderNotification::DidUpdateTrash) .payload(RepeatedTrashPB { items: vec![] }) .send(); } + /// Delete the trash permanently. + /// Delete the view will delete all the resources that the view holds. For example, if the view + /// is a database view. Then the database will be deleted as well. + #[tracing::instrument(level = "debug", skip(self, view_id), err)] + pub async fn delete_trash(&self, view_id: &str) -> FlowyResult<()> { + let view = self.with_folder(None, |folder| folder.views.get_view(view_id)); + self.with_folder((), |folder| { + folder.trash.delete_trash(vec![view_id]); + folder.views.delete_views(vec![view_id]); + }); + if let Some(view) = view { + if let Ok(handler) = self.get_handler(&view.layout) { + handler.delete_view(view_id).await?; + } + } + Ok(()) + } + pub(crate) async fn import(&self, import_data: ImportParams) -> FlowyResult { if import_data.data.is_none() && import_data.file_path.is_none() { return Err(FlowyError::new( diff --git a/frontend/rust-lib/flowy-folder2/src/view_operation.rs b/frontend/rust-lib/flowy-folder2/src/view_operation.rs index ca37523ba6..2113e30b17 100644 --- a/frontend/rust-lib/flowy-folder2/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder2/src/view_operation.rs @@ -1,18 +1,20 @@ -use crate::entities::{CreateViewParams, ViewLayoutPB}; -use bytes::Bytes; -use collab_folder::core::{RepeatedView, ViewIdentifier, ViewLayout}; -use flowy_error::FlowyError; -use lib_infra::future::FutureResult; -use lib_infra::util::timestamp; - use std::collections::HashMap; use std::future::Future; use std::sync::Arc; -pub type ViewData = Bytes; +use bytes::Bytes; pub use collab_folder::core::View; +use collab_folder::core::{RepeatedView, ViewIdentifier, ViewLayout}; use tokio::sync::RwLock; +use flowy_error::FlowyError; +use lib_infra::future::FutureResult; +use lib_infra::util::timestamp; + +use crate::entities::{CreateViewParams, ViewLayoutPB}; + +pub type ViewData = Bytes; + /// A builder for creating a view for a workspace. /// The views created by this builder will be the first level views of the workspace. pub struct WorkspaceViewBuilder { @@ -157,6 +159,10 @@ pub trait FolderOperationHandler { /// the backend fn close_view(&self, view_id: &str) -> FutureResult<(), 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>; + /// Returns the [ViewData] that can be used to create the same view. fn duplicate_view(&self, view_id: &str) -> FutureResult;