Skip to content

Commit e5703f8

Browse files
authored
fix: duplicate trash (#1818)
1 parent e77fef3 commit e5703f8

File tree

4 files changed

+35
-97
lines changed

4 files changed

+35
-97
lines changed

frontend/app_flowy/test/bloc_test/home_test/trash_bloc_test.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,14 @@ void main() {
8383
context.appBloc.add(AppEvent.deleteView(view.id));
8484
await blocResponseFuture();
8585
}
86-
assert(trashBloc.state.objects[0].id == context.allViews[0].id);
87-
assert(trashBloc.state.objects[1].id == context.allViews[1].id);
88-
assert(trashBloc.state.objects[2].id == context.allViews[2].id);
86+
expect(trashBloc.state.objects[0].id, context.allViews[0].id);
87+
expect(trashBloc.state.objects[1].id, context.allViews[1].id);
88+
expect(trashBloc.state.objects[2].id, context.allViews[2].id);
8989

9090
// delete a view permanently
9191
trashBloc.add(TrashEvent.delete(trashBloc.state.objects[0]));
9292
await blocResponseFuture();
93-
assert(trashBloc.state.objects.length == 2,
94-
"but receive ${trashBloc.state.objects.length}");
93+
expect(trashBloc.state.objects.length, 2);
9594

9695
// delete all view permanently
9796
trashBloc.add(const TrashEvent.deleteAll());

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

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -282,22 +282,38 @@ impl FolderPad {
282282
}
283283

284284
pub fn create_trash(&mut self, trash: Vec<TrashRevision>) -> SyncResult<Option<FolderChangeset>> {
285-
self.with_trash(|t| {
286-
let mut new_trash = trash.into_iter().map(Arc::new).collect::<Vec<Arc<TrashRevision>>>();
287-
t.append(&mut new_trash);
288-
289-
Ok(Some(()))
285+
self.with_trash(|original_trash| {
286+
let mut new_trash = trash
287+
.into_iter()
288+
.flat_map(|new_trash| {
289+
if original_trash.iter().any(|old_trash| old_trash.id == new_trash.id) {
290+
None
291+
} else {
292+
Some(Arc::new(new_trash))
293+
}
294+
})
295+
.collect::<Vec<Arc<TrashRevision>>>();
296+
if new_trash.is_empty() {
297+
Ok(None)
298+
} else {
299+
original_trash.append(&mut new_trash);
300+
Ok(Some(()))
301+
}
290302
})
291303
}
292304

293305
pub fn read_trash(&self, trash_id: Option<String>) -> SyncResult<Vec<TrashRevision>> {
294306
match trash_id {
295-
None => Ok(self
296-
.folder_rev
297-
.trash
298-
.iter()
299-
.map(|t| t.as_ref().clone())
300-
.collect::<Vec<TrashRevision>>()),
307+
None => {
308+
// Removes the duplicate items if exist
309+
let mut trash_items = Vec::<TrashRevision>::with_capacity(self.folder_rev.trash.len());
310+
for trash_item in self.folder_rev.trash.iter() {
311+
if !trash_items.iter().any(|item| item.id == trash_item.id) {
312+
trash_items.push(trash_item.as_ref().clone());
313+
}
314+
}
315+
Ok(trash_items)
316+
}
301317
Some(trash_id) => match self.folder_rev.trash.iter().find(|t| t.id == trash_id) {
302318
Some(trash) => Ok(vec![trash.as_ref().clone()]),
303319
None => Ok(vec![]),

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

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use tokio::sync::{broadcast, mpsc};
1313
pub struct TrashController {
1414
persistence: Arc<FolderPersistence>,
1515
notify: broadcast::Sender<TrashEvent>,
16+
#[allow(dead_code)]
1617
cloud_service: Arc<dyn FolderCouldServiceV1>,
18+
#[allow(dead_code)]
1719
user: Arc<dyn WorkspaceUser>,
1820
}
1921

@@ -54,11 +56,6 @@ impl TrashController {
5456
ty: trash.ty.into(),
5557
};
5658

57-
self.delete_trash_on_server(RepeatedTrashIdPB {
58-
items: vec![identifier.clone()],
59-
delete_all: false,
60-
})?;
61-
6259
tracing::Span::current().record("putback", format!("{:?}", &identifier).as_str());
6360
let _ = self.notify.send(TrashEvent::Putback(vec![identifier].into(), tx));
6461
rx.recv().await.unwrap()?;
@@ -82,7 +79,6 @@ impl TrashController {
8279
let _ = rx.recv().await;
8380

8481
notify_trash_changed(RepeatedTrashPB { items: vec![] });
85-
self.delete_all_trash_on_server().await?;
8682
Ok(())
8783
}
8884

@@ -97,7 +93,6 @@ impl TrashController {
9793
self.delete_with_identifiers(all_trash_identifiers).await?;
9894

9995
notify_trash_changed(RepeatedTrashPB { items: vec![] });
100-
self.delete_all_trash_on_server().await?;
10196
Ok(())
10297
}
10398

@@ -110,7 +105,6 @@ impl TrashController {
110105
.await?;
111106

112107
notify_trash_changed(trash_revs);
113-
self.delete_trash_on_server(trash_identifiers)?;
114108

115109
Ok(())
116110
}
@@ -169,8 +163,6 @@ impl TrashController {
169163
self.persistence
170164
.begin_transaction(|transaction| {
171165
transaction.create_trash(trash_revs.clone())?;
172-
let _ = self.create_trash_on_server(trash_revs);
173-
174166
notify_trash_changed(transaction.read_trash(None)?);
175167
Ok(())
176168
})
@@ -194,7 +186,6 @@ impl TrashController {
194186
.map(|trash_rev| trash_rev.into())
195187
.collect();
196188

197-
self.read_trash_on_server()?;
198189
Ok(RepeatedTrashPB { items })
199190
}
200191

@@ -211,74 +202,6 @@ impl TrashController {
211202
}
212203
}
213204

214-
impl TrashController {
215-
#[tracing::instrument(level = "trace", skip(self, trash), err)]
216-
fn create_trash_on_server<T: Into<RepeatedTrashIdPB>>(&self, trash: T) -> FlowyResult<()> {
217-
let token = self.user.token()?;
218-
let trash_identifiers = trash.into();
219-
let server = self.cloud_service.clone();
220-
// TODO: retry?
221-
let _ = tokio::spawn(async move {
222-
match server.create_trash(&token, trash_identifiers).await {
223-
Ok(_) => {}
224-
Err(e) => log::error!("Create trash failed: {:?}", e),
225-
}
226-
});
227-
Ok(())
228-
}
229-
230-
#[tracing::instrument(level = "trace", skip(self, trash), err)]
231-
fn delete_trash_on_server<T: Into<RepeatedTrashIdPB>>(&self, trash: T) -> FlowyResult<()> {
232-
let token = self.user.token()?;
233-
let trash_identifiers = trash.into();
234-
let server = self.cloud_service.clone();
235-
let _ = tokio::spawn(async move {
236-
match server.delete_trash(&token, trash_identifiers).await {
237-
Ok(_) => {}
238-
Err(e) => log::error!("Delete trash failed: {:?}", e),
239-
}
240-
});
241-
Ok(())
242-
}
243-
244-
#[tracing::instrument(level = "trace", skip(self), err)]
245-
fn read_trash_on_server(&self) -> FlowyResult<()> {
246-
let token = self.user.token()?;
247-
let server = self.cloud_service.clone();
248-
let persistence = self.persistence.clone();
249-
250-
tokio::spawn(async move {
251-
match server.read_trash(&token).await {
252-
Ok(trash_rev) => {
253-
tracing::debug!("Remote trash count: {}", trash_rev.len());
254-
let result = persistence
255-
.begin_transaction(|transaction| {
256-
transaction.create_trash(trash_rev.clone())?;
257-
transaction.read_trash(None)
258-
})
259-
.await;
260-
261-
match result {
262-
Ok(trash_revs) => {
263-
notify_trash_changed(trash_revs);
264-
}
265-
Err(e) => log::error!("Save trash failed: {:?}", e),
266-
}
267-
}
268-
Err(e) => log::error!("Read trash failed: {:?}", e),
269-
}
270-
});
271-
Ok(())
272-
}
273-
274-
#[tracing::instrument(level = "trace", skip(self), err)]
275-
async fn delete_all_trash_on_server(&self) -> FlowyResult<()> {
276-
let token = self.user.token()?;
277-
let server = self.cloud_service.clone();
278-
server.delete_trash(&token, RepeatedTrashIdPB::all()).await
279-
}
280-
}
281-
282205
#[tracing::instrument(level = "debug", skip(repeated_trash), fields(n_trash))]
283206
fn notify_trash_changed<T: Into<RepeatedTrashPB>>(repeated_trash: T) {
284207
let repeated_trash = repeated_trash.into();

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use serde::de::Visitor;
22
use serde::{Deserialize, Serialize};
33
use serde_repr::*;
44
use std::fmt;
5-
#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
5+
#[derive(Default, Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
66
pub struct TrashRevision {
77
pub id: String,
88

@@ -17,7 +17,7 @@ pub struct TrashRevision {
1717
pub ty: TrashTypeRevision,
1818
}
1919

20-
#[derive(Eq, PartialEq, Debug, Clone, Serialize_repr)]
20+
#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize_repr)]
2121
#[repr(u8)]
2222
pub enum TrashTypeRevision {
2323
Unknown = 0,

0 commit comments

Comments
 (0)