diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs index d08402ba4..28947ea4b 100644 --- a/crates/ui-egui/src/state.rs +++ b/crates/ui-egui/src/state.rs @@ -677,7 +677,7 @@ pub enum Dialog { /// What the scan found (`None` while it runs). counts: Option, import_new: bool, - #[serde(default)] + #[serde(default = "yes")] relink_moved: bool, remove_missing: bool, read_metadata: bool, @@ -686,6 +686,10 @@ pub enum Dialog { Shortcuts, } +fn yes() -> bool { + true +} + /// How many changes a Synchronize Folder scan found, by kind. #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] diff --git a/crates/ui-egui/src/sync.rs b/crates/ui-egui/src/sync.rs index 642de3e5e..c44bc9421 100644 --- a/crates/ui-egui/src/sync.rs +++ b/crates/ui-egui/src/sync.rs @@ -173,13 +173,17 @@ pub fn confirm(app: &mut LightcraftApp, dlg: &Dialog) -> Result { ); app.sync_owns_changes = false; if r.is_err() { - // (the folder changed since the scan, or went offline): look again, in the background - let (path, disk) = (path.clone(), *disk); + // (the folder changed since the scan, or went offline): look again, in the background, + // keeping what was ticked; the error is what is reported, not a failure to look again let name = match dlg { Dialog::SynchronizeFolder { name, .. } => name.clone(), _ => String::new(), }; - open(app, &path, &name, disk)?; + if open(app, path, &name, *disk).is_ok() + && let Some(Dialog::SynchronizeFolder { import_new: i, relink_moved: l, remove_missing: m, read_metadata: x, .. }) = &mut app.ui.dialog + { + (*i, *l, *m, *x) = (*import_new, *relink_moved, *remove_missing, *read_metadata); + } } r } diff --git a/crates/ui-egui/src/tests_sync.rs b/crates/ui-egui/src/tests_sync.rs index 631aaa6b5..d4ccd0ad3 100644 --- a/crates/ui-egui/src/tests_sync.rs +++ b/crates/ui-egui/src/tests_sync.rs @@ -167,6 +167,9 @@ fn a_scan_gone_stale_in_the_dialog_is_made_again_in_the_background() { let dir = Scratch::new("restale"); let mut h = changed_folder(&dir); open_and_scan(&mut h, &dir.path("trip")); + let r = h.request("ui.clickWidget", json!({"id": "syncRemoveMissing"}), T); + assert_eq!(r["ok"], true, "{r}"); + h.step(); // a photo of the folder changes while the dialog is open let a = h.app.session.catalog.photos().find(|p| p.file_name == "a.png").unwrap().id; let r = h.request("engine.execute", json!({"command": "photo.rate", "params": {"ids": [a.0], "rating": 3}}), T); @@ -177,7 +180,8 @@ fn a_scan_gone_stale_in_the_dialog_is_made_again_in_the_background() { assert!(matches!(h.app.ui.dialog, Some(Dialog::SynchronizeFolder { .. })), "the dialog stays open"); let rescanned = h.step_until(T, |h| matches!(&h.app.ui.dialog, Some(Dialog::SynchronizeFolder { counts: Some(_), .. }))); assert!(rescanned, "and scans again"); + assert!(matches!(h.app.ui.dialog, Some(Dialog::SynchronizeFolder { remove_missing: true, .. })), "keeping what was ticked"); let r = h.request("ui.dialog.confirm", json!({}), T); assert_eq!(r["ok"], true, "{r}"); - assert_eq!(in_library(&h), vec!["a.png", "b.png", "c.png"]); + assert_eq!(in_library(&h), vec!["a.png", "c.png"], "c came in, the missing b went"); }