Nathan.fooo 2 лет назад
Родитель
Сommit
e5703f83fb

+ 4 - 5
frontend/app_flowy/test/bloc_test/home_test/trash_bloc_test.dart

@@ -83,15 +83,14 @@ void main() {
         context.appBloc.add(AppEvent.deleteView(view.id));
         context.appBloc.add(AppEvent.deleteView(view.id));
         await blocResponseFuture();
         await blocResponseFuture();
       }
       }
-      assert(trashBloc.state.objects[0].id == context.allViews[0].id);
-      assert(trashBloc.state.objects[1].id == context.allViews[1].id);
-      assert(trashBloc.state.objects[2].id == context.allViews[2].id);
+      expect(trashBloc.state.objects[0].id, context.allViews[0].id);
+      expect(trashBloc.state.objects[1].id, context.allViews[1].id);
+      expect(trashBloc.state.objects[2].id, context.allViews[2].id);
 
 
       // delete a view permanently
       // delete a view permanently
       trashBloc.add(TrashEvent.delete(trashBloc.state.objects[0]));
       trashBloc.add(TrashEvent.delete(trashBloc.state.objects[0]));
       await blocResponseFuture();
       await blocResponseFuture();
-      assert(trashBloc.state.objects.length == 2,
-          "but receive ${trashBloc.state.objects.length}");
+      expect(trashBloc.state.objects.length, 2);
 
 
       // delete all view permanently
       // delete all view permanently
       trashBloc.add(const TrashEvent.deleteAll());
       trashBloc.add(const TrashEvent.deleteAll());

+ 27 - 11
frontend/rust-lib/flowy-client-sync/src/client_folder/folder_pad.rs

@@ -282,22 +282,38 @@ impl FolderPad {
     }
     }
 
 
     pub fn create_trash(&mut self, trash: Vec<TrashRevision>) -> SyncResult<Option<FolderChangeset>> {
     pub fn create_trash(&mut self, trash: Vec<TrashRevision>) -> SyncResult<Option<FolderChangeset>> {
-        self.with_trash(|t| {
-            let mut new_trash = trash.into_iter().map(Arc::new).collect::<Vec<Arc<TrashRevision>>>();
-            t.append(&mut new_trash);
-
-            Ok(Some(()))
+        self.with_trash(|original_trash| {
+            let mut new_trash = trash
+                .into_iter()
+                .flat_map(|new_trash| {
+                    if original_trash.iter().any(|old_trash| old_trash.id == new_trash.id) {
+                        None
+                    } else {
+                        Some(Arc::new(new_trash))
+                    }
+                })
+                .collect::<Vec<Arc<TrashRevision>>>();
+            if new_trash.is_empty() {
+                Ok(None)
+            } else {
+                original_trash.append(&mut new_trash);
+                Ok(Some(()))
+            }
         })
         })
     }
     }
 
 
     pub fn read_trash(&self, trash_id: Option<String>) -> SyncResult<Vec<TrashRevision>> {
     pub fn read_trash(&self, trash_id: Option<String>) -> SyncResult<Vec<TrashRevision>> {
         match trash_id {
         match trash_id {
-            None => Ok(self
-                .folder_rev
-                .trash
-                .iter()
-                .map(|t| t.as_ref().clone())
-                .collect::<Vec<TrashRevision>>()),
+            None => {
+                // Removes the duplicate items if exist
+                let mut trash_items = Vec::<TrashRevision>::with_capacity(self.folder_rev.trash.len());
+                for trash_item in self.folder_rev.trash.iter() {
+                    if !trash_items.iter().any(|item| item.id == trash_item.id) {
+                        trash_items.push(trash_item.as_ref().clone());
+                    }
+                }
+                Ok(trash_items)
+            }
             Some(trash_id) => match self.folder_rev.trash.iter().find(|t| t.id == trash_id) {
             Some(trash_id) => match self.folder_rev.trash.iter().find(|t| t.id == trash_id) {
                 Some(trash) => Ok(vec![trash.as_ref().clone()]),
                 Some(trash) => Ok(vec![trash.as_ref().clone()]),
                 None => Ok(vec![]),
                 None => Ok(vec![]),

+ 2 - 79
frontend/rust-lib/flowy-folder/src/services/trash/controller.rs

@@ -13,7 +13,9 @@ use tokio::sync::{broadcast, mpsc};
 pub struct TrashController {
 pub struct TrashController {
     persistence: Arc<FolderPersistence>,
     persistence: Arc<FolderPersistence>,
     notify: broadcast::Sender<TrashEvent>,
     notify: broadcast::Sender<TrashEvent>,
+    #[allow(dead_code)]
     cloud_service: Arc<dyn FolderCouldServiceV1>,
     cloud_service: Arc<dyn FolderCouldServiceV1>,
+    #[allow(dead_code)]
     user: Arc<dyn WorkspaceUser>,
     user: Arc<dyn WorkspaceUser>,
 }
 }
 
 
@@ -54,11 +56,6 @@ impl TrashController {
             ty: trash.ty.into(),
             ty: trash.ty.into(),
         };
         };
 
 
-        self.delete_trash_on_server(RepeatedTrashIdPB {
-            items: vec![identifier.clone()],
-            delete_all: false,
-        })?;
-
         tracing::Span::current().record("putback", format!("{:?}", &identifier).as_str());
         tracing::Span::current().record("putback", format!("{:?}", &identifier).as_str());
         let _ = self.notify.send(TrashEvent::Putback(vec![identifier].into(), tx));
         let _ = self.notify.send(TrashEvent::Putback(vec![identifier].into(), tx));
         rx.recv().await.unwrap()?;
         rx.recv().await.unwrap()?;
@@ -82,7 +79,6 @@ impl TrashController {
         let _ = rx.recv().await;
         let _ = rx.recv().await;
 
 
         notify_trash_changed(RepeatedTrashPB { items: vec![] });
         notify_trash_changed(RepeatedTrashPB { items: vec![] });
-        self.delete_all_trash_on_server().await?;
         Ok(())
         Ok(())
     }
     }
 
 
@@ -97,7 +93,6 @@ impl TrashController {
         self.delete_with_identifiers(all_trash_identifiers).await?;
         self.delete_with_identifiers(all_trash_identifiers).await?;
 
 
         notify_trash_changed(RepeatedTrashPB { items: vec![] });
         notify_trash_changed(RepeatedTrashPB { items: vec![] });
-        self.delete_all_trash_on_server().await?;
         Ok(())
         Ok(())
     }
     }
 
 
@@ -110,7 +105,6 @@ impl TrashController {
             .await?;
             .await?;
 
 
         notify_trash_changed(trash_revs);
         notify_trash_changed(trash_revs);
-        self.delete_trash_on_server(trash_identifiers)?;
 
 
         Ok(())
         Ok(())
     }
     }
@@ -169,8 +163,6 @@ impl TrashController {
         self.persistence
         self.persistence
             .begin_transaction(|transaction| {
             .begin_transaction(|transaction| {
                 transaction.create_trash(trash_revs.clone())?;
                 transaction.create_trash(trash_revs.clone())?;
-                let _ = self.create_trash_on_server(trash_revs);
-
                 notify_trash_changed(transaction.read_trash(None)?);
                 notify_trash_changed(transaction.read_trash(None)?);
                 Ok(())
                 Ok(())
             })
             })
@@ -194,7 +186,6 @@ impl TrashController {
             .map(|trash_rev| trash_rev.into())
             .map(|trash_rev| trash_rev.into())
             .collect();
             .collect();
 
 
-        self.read_trash_on_server()?;
         Ok(RepeatedTrashPB { items })
         Ok(RepeatedTrashPB { items })
     }
     }
 
 
@@ -211,74 +202,6 @@ impl TrashController {
     }
     }
 }
 }
 
 
-impl TrashController {
-    #[tracing::instrument(level = "trace", skip(self, trash), err)]
-    fn create_trash_on_server<T: Into<RepeatedTrashIdPB>>(&self, trash: T) -> FlowyResult<()> {
-        let token = self.user.token()?;
-        let trash_identifiers = trash.into();
-        let server = self.cloud_service.clone();
-        // TODO: retry?
-        let _ = tokio::spawn(async move {
-            match server.create_trash(&token, trash_identifiers).await {
-                Ok(_) => {}
-                Err(e) => log::error!("Create trash failed: {:?}", e),
-            }
-        });
-        Ok(())
-    }
-
-    #[tracing::instrument(level = "trace", skip(self, trash), err)]
-    fn delete_trash_on_server<T: Into<RepeatedTrashIdPB>>(&self, trash: T) -> FlowyResult<()> {
-        let token = self.user.token()?;
-        let trash_identifiers = trash.into();
-        let server = self.cloud_service.clone();
-        let _ = tokio::spawn(async move {
-            match server.delete_trash(&token, trash_identifiers).await {
-                Ok(_) => {}
-                Err(e) => log::error!("Delete trash failed: {:?}", e),
-            }
-        });
-        Ok(())
-    }
-
-    #[tracing::instrument(level = "trace", skip(self), err)]
-    fn read_trash_on_server(&self) -> FlowyResult<()> {
-        let token = self.user.token()?;
-        let server = self.cloud_service.clone();
-        let persistence = self.persistence.clone();
-
-        tokio::spawn(async move {
-            match server.read_trash(&token).await {
-                Ok(trash_rev) => {
-                    tracing::debug!("Remote trash count: {}", trash_rev.len());
-                    let result = persistence
-                        .begin_transaction(|transaction| {
-                            transaction.create_trash(trash_rev.clone())?;
-                            transaction.read_trash(None)
-                        })
-                        .await;
-
-                    match result {
-                        Ok(trash_revs) => {
-                            notify_trash_changed(trash_revs);
-                        }
-                        Err(e) => log::error!("Save trash failed: {:?}", e),
-                    }
-                }
-                Err(e) => log::error!("Read trash failed: {:?}", e),
-            }
-        });
-        Ok(())
-    }
-
-    #[tracing::instrument(level = "trace", skip(self), err)]
-    async fn delete_all_trash_on_server(&self) -> FlowyResult<()> {
-        let token = self.user.token()?;
-        let server = self.cloud_service.clone();
-        server.delete_trash(&token, RepeatedTrashIdPB::all()).await
-    }
-}
-
 #[tracing::instrument(level = "debug", skip(repeated_trash), fields(n_trash))]
 #[tracing::instrument(level = "debug", skip(repeated_trash), fields(n_trash))]
 fn notify_trash_changed<T: Into<RepeatedTrashPB>>(repeated_trash: T) {
 fn notify_trash_changed<T: Into<RepeatedTrashPB>>(repeated_trash: T) {
     let repeated_trash = repeated_trash.into();
     let repeated_trash = repeated_trash.into();

+ 2 - 2
shared-lib/folder-model/src/trash_rev.rs

@@ -2,7 +2,7 @@ use serde::de::Visitor;
 use serde::{Deserialize, Serialize};
 use serde::{Deserialize, Serialize};
 use serde_repr::*;
 use serde_repr::*;
 use std::fmt;
 use std::fmt;
-#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
+#[derive(Default, Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
 pub struct TrashRevision {
 pub struct TrashRevision {
     pub id: String,
     pub id: String,
 
 
@@ -17,7 +17,7 @@ pub struct TrashRevision {
     pub ty: TrashTypeRevision,
     pub ty: TrashTypeRevision,
 }
 }
 
 
-#[derive(Eq, PartialEq, Debug, Clone, Serialize_repr)]
+#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize_repr)]
 #[repr(u8)]
 #[repr(u8)]
 pub enum TrashTypeRevision {
 pub enum TrashTypeRevision {
     Unknown = 0,
     Unknown = 0,